3天时间,我是如何解决redis bigkey 删除问题的?( 三 )
(1)要思考一下可不可以做一些优化(例如拆分数据结构)尽量让这些bigkey消失在业务中 ,
(2)如果bigkey不可避免 , 也要思考一下要不要每次把所有元素都取出来(例如有时候仅仅需要hmget , 而不是hgetall) 。
(3)最后 , 可喜的是 , Redis将在4.0版本支持lazy delete free的模式 , 那时删除bigkey不会阻塞Redis 。
如何优雅的删除重构重新构建自己的业务 key 。
让 key/value 更加小 , 使用纯字符串 。
- 缺点
使用 lazy free这个是 redis 4.0 以后的特性 。
可能会受限于版本 , 导致无法使用 。
- 查看版本
Redis 2.8 release notes=======================** IMPORTANT ** Check the 'Migrating from 2.6 to 2.8' section at the end ofthis file for information about what changed between 2.6 and2.8 and how this may affect your application.--------------------------------------------------------------------------------Upgrade urgency levels:LOW:No need to upgrade unless there are new features you want to use.MODERATE: Program an upgrade of the server, but it's not urgent.HIGH:There is a critical bug that may affect a subset of users. Upgrade!CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP.----------------------------------------------------------------------------------[ Redis 2.8.6 ] Release date: 13 Feb 2014
可知当前版本为:2.8.6使用 expire 设置过期需要熟知 redis 的淘汰策略 。
(1)惰性淘汰
(2)定时删除
(3)定期删除
其中定期删除 , 是一个异步的进程去处理的 , 不会阻塞主进程 。
其中设置超时时间 , 是为了限制每一次的操作时间 , 从而更好的清空数据 , 释放内存 。
- 缺点
对内存是不够友好的
可能要根据业务进行调整 , 比如本来显式删除 , 可以放在凌晨 。
如果使用定期删除 , 被淘汰的时间就变得不固定了 。
实战代码示例【3天时间,我是如何解决redis bigkey 删除问题的?】
/** * 刪除 BIG key * 应用场景:对于 big key , 可以使用 hscan 首先分批次删除 , 最后统一删除 * (1)比直接删除的耗时变长 , 但是不会产生慢操作 。* (2)新业务实现尽可能拆开 , 不要依赖此方法 。* @param key key * @param scanCount 单次扫描总数(建议值:100) * @param intervalMills 分批次的等待时间(建议值:5) */void removeBigKey(final String key, final int scanCount, final long intervalMills)
实现JedisCluster jedisCluster = redisClusterTemplate.getJedisClusterInstance();// 游标初始值为0String cursor = ScanParams.SCAN_POINTER_START;ScanParams scanParams = new ScanParams();scanParams.count(scanCount);while (true) { // 每次扫描后获取新的游标 ScanResult scanResult = jedisCluster.hscan(key, cursor, scanParams); cursor = scanResult.getStringCursor(); // 获取扫描结果为空 List list = scanResult.getResult(); if (CollectionUtils.isEmpty(list)) {break; } // 构建多个删除的 key String[] fields = getFieldsKeyArray(list); jedisCluster.hdel(key, fields); // 游标为0时停止 if (ScanParams.SCAN_POINTER_START.equals(cursor)) {break; } // 沉睡等待 , 避免对 redis 压力太大 DateUtil.sleepInterval(intervalMills, TimeUnit.MILLISECONDS);}// 执行 key 本身的删除jedisCluster.del(key);
- 给闲置的极路由器刷高格固件控制小孩看动画片时间
- 台积电也没有想到,仅一天时间,华为就成了最后的赢家?
- 仅一天时间!5G为何突然不火了?三星却做到了6G世界第一?
- 如何在短时间内快速成为软件开发专家
- 你只写了两行代码,为什么要花两天时间?
- 有颜有料,给MacBook Pro配个贝尔金雷电3扩展坞
- TCP 窗口缩放、时间戳和 SACK
- 家庭保险智能管家,米家智能保管箱体验
- 合肥APP开发公司-app开发时间和什么有关
- 国外快递成功“入侵”,半年时间就日单千万!三通一达彻底慌了