- 浏览: 45372 次
最新评论
首先定义个工具interface,基于Java 8的实现.
主要利用了Redis Cluster的hashTags特性。详细细节可前往https://redis.io/topics/cluster-spec的Keys hash tags章节了解。
个人建议还是看完这个规范的前半部分才好理解,为什么会出现hash tags这个东西。
然后后面是针对同一接口的不同分页的缓存数据的key的设置,配合hash tags 的操作。
主要利用了Redis Cluster的hashTags特性。详细细节可前往https://redis.io/topics/cluster-spec的Keys hash tags章节了解。
个人建议还是看完这个规范的前半部分才好理解,为什么会出现hash tags这个东西。
package com.xxxx.cms.common.support; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.apache.commons.collections4.CollectionUtils; import com.google.common.collect.Lists; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisCluster; import redis.clients.jedis.JedisPool; import redis.clients.util.JedisClusterCRC16; public interface RedisCacheSupporter { String SEPARATOR = RedisCacheBase.staticSeparator(); String CONJUNCTION = RedisCacheBase.staticConjunction(); String PLACEHOLDER = RedisCacheBase.staticPlaceHolder(); String LEFT_TAG_STR = RedisCacheBase.staticLeftTagStr(); String RIGHT_TAG_STR = RedisCacheBase.staticRightTagStr(); static String hashTagsPrefix(String cacheKeyPrefix) { return LEFT_TAG_STR + cacheKeyPrefix + RIGHT_TAG_STR; } static TreeSet<String> keys(JedisCluster jedisClusterClient, String cachePrefix) { Map<String, JedisPool> clusterNodes = jedisClusterClient.getClusterNodes(); TreeSet<String> keys = new TreeSet<>(); String strPattern = cachePrefix + "*"; for (String k : clusterNodes.keySet()) { JedisPool jp = clusterNodes.get(k); try (Jedis jedis = jp.getResource();) { if (jedis.info("replication").contains("role:slave")) continue; Set<String> keysInNode = jedis.keys(strPattern); keys.addAll(keysInNode); } } return keys; } static boolean delByKey(JedisCluster jedisClusterClient, String cacheKey) { return jedisClusterClient.del(cacheKey) > 0; } /** * 缓存前缀通过hash tags {@link #hashTagsPrefix(String)}处理过的key首选使用本方法 * <br/> * <br/> * hash tags在redis集群reSharding时,不能保证都在同一slot下,所以为代码健壮性考虑可首先调用本方法再捕获异常中调用{@link #delLoopNodesByPrefix(JedisCluster, String)}方法处理 * @param jedisClusterClient * @param cachePrefix */ static void delAllByPrefix(JedisCluster jedisClusterClient, String cachePrefix) { Set<String> keys = keys(jedisClusterClient, cachePrefix); if (CollectionUtils.isEmpty(keys)) { return; } jedisClusterClient.del(keys.toArray(new String[keys.size()])); } static void delLoopNodesByPrefix(JedisCluster jedisClusterClient, String cachePrefix) { String keysPattern = cachePrefix + "*"; Map<String, JedisPool> clusterNodes = jedisClusterClient.getClusterNodes(); for (String k : clusterNodes.keySet()) { JedisPool jedisPool = clusterNodes.get(k); try (Jedis jedis = jedisPool.getResource()) { if (jedis.info("replication").contains("role:slave")) continue;// 从节点不处理 Set<String> keys = jedis.keys(keysPattern); if (keys.size() <= 0) continue; Map<Integer, List<String>> map = new HashMap<>(); for (String key : keys) { // cluster模式执行多key操作的时候,这些key必须在同一个slot上 // 不然会报:redis.clients.jedis.exceptions.JedisClusterException: // No way to dispatch this command to Redis Cluster because keys have different slots. int slot = JedisClusterCRC16.getSlot(key); // 按slot将key分组,相同slot的key一起提交 if (map.containsKey(slot)) { map.get(slot).add(key); } else { map.put(slot, Lists.newArrayList(key)); } } for (Integer slotKey : map.keySet()) { jedis.del(map.get(slotKey).toArray(new String[map.get(slotKey).size()])); } } } } }
然后后面是针对同一接口的不同分页的缓存数据的key的设置,配合hash tags 的操作。
package com.xxxxx.cms.stock.common.support; import com.xxxxx.cms.common.support.RedisCacheSupporter; import redis.clients.jedis.JedisCluster; public interface CachePrefix { String BASE_PREFIX = "cms:stock:plate:"; interface interfaceSpc { String PREFIX = BASE_PREFIX + "interface" + RedisCacheSupporter.SEPARATOR; static String contents(String plateCode) { return RedisCacheSupporter.hashTagsPrefix(PREFIX + "contents" + RedisCacheSupporter.SEPARATOR + plateCode + RedisCacheSupporter.SEPARATOR); } static void delCotentsAllCache(JedisCluster jedisClusterClient, String plateCode) { try { RedisCacheSupporter.delAllByPrefix(jedisClusterClient, contents(plateCode)); } catch (Exception e) { e.printStackTrace(); RedisCacheSupporter.delLoopNodesByPrefix(jedisClusterClient, contents(plateCode)); } } } }
发表评论
-
简单的压测模拟
2018-05-11 19:52 638import java.time.Duration; i ... -
Java的驼峰与下划线的属性对象互相转换
2018-05-11 19:50 8321import com.xxxx.util.consta ... -
Elastic Search搜索实例
2019-06-16 18:30 531要从现在的公司离职了。记录一下自己针对我们的自己需求所做的搜索 ... -
简单ELK配合logback搭建日志监控中心
2018-03-20 17:30 1299今天得闲就自己搭了个ELK示例,过程挺简单的。 Elas ... -
spring的基于java的项目配置示例2
2018-03-20 17:32 785import com.xxx.support.config ... -
HttpClient实例
2018-03-16 08:15 618import java.io.IOException; ... -
spring的基于java的项目配置示例1
2018-03-16 08:26 887spring的基于java的项目配置示例。 impor ... -
基于spring data的Elastic Search的配置示例
2018-03-15 17:41 878基于spring data的Elastic Search的配置 ... -
方便jedis cluster操作的工具类
2018-03-15 17:37 2913由于redis的集群 redis cluster不支持keys ... -
爬虫基础类
2018-03-15 17:28 762自己封装的爬虫基础类。 public interfac ... -
基于AOP的ajax的referrer判断
2018-03-15 17:23 1525网页中ajax请求的referrer的值是当前域名。(其实这个 ... -
Java Timestamp从MySQL数据库取出的字符串转换为LocalDateTime
2016-01-26 16:08 9863最新在工作中使用了Java 8的LocalDate ... -
reviewC指针
2014-03-02 22:05 372由于要考试,有C的考核内容。所以今天把C拉出来又看了下,其实基 ... -
Python2.X内置函数学习
2013-12-19 21:52 11331.apply()函数 学过Python的都知道P ... -
学习Python中遇到的问题
2013-09-04 23:26 684最近学习Python中。 先上代码: # -*- codi ...
相关推荐
#资源达人分享计划#
Flasher为国内某大型一线电商平台的分布式缓存框架,基于Redis Cluster实现的Java客户端
区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类...
组建redis cluster的脚本
Redis-Cluster集群模式部署
缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用) 2. 分布式集群架构中的session分离。 3. 聊天室的在线好友列表。 4. 任务队列。(秒杀、抢购、12306等等) 5. 应用排行榜。 6. 网站访问统计...
redis集群采用无中心节点方式实现,无需proxy代理,客户端直接与redis集群的每个节点连接,根据同样的hash算法计算出key对应的slot,然后直接在slot对应的redisj节点上执行命令。在redis看来,响应时间是最苛刻的...
rediscluster高可用集群搭建手册,从0 到1 完美的实现 redis集群搭建 redis5种数据类型
redis-go-cluster, 在Go中,redis集群客户端实现 redis-go-clusterredis-go-cluster是基于 burd burd burd的客户端的一个golang实现的。 它在本地缓存 slot 信息,并在集群更改时自动更新。 客户端管理每个 node的...
redis清理缓存、查询工具,可以支持sentinel模式和cluster模式
redis高可用笔记
redis cluster 是很流行的缓存机制,本人配合博客上传部分配置,给大家参考学习。有需要可以看我的博客,配置只是辅助。有错误还请 指教
redis-cluster 组件脚本
基于Redis Cluster打造的缓存系统。经过不断的迭代研发,目前已形成一整套自动化运维体系:涵盖一键运维集群、细粒度的监控、支持自动扩缩容以及热点Key监控等完整的解决方案。同时服务端通过Docker进行部署,最大...
redis windon最新免安装版本,Redis 是一个开源(BSD 许可)的内存中数据结构存储,用作数据库、缓存、消息代理和流引擎。Redis 提供数据结构,例如字符串、散列、列表、集合、带有范围查询的排序集、位图、超日志、...
主要新特性包括:Redis Cluster,Redis子集的分布式实现;新的“嵌套字符串”对象编码减少缓存遗漏,大幅提高某些工作负荷的速度;等等。开发者Salvatore Sanfilippo表示,Redis 3.0.0是第一个原生支持集群的稳定...
Redis(TM)是高级键值缓存和存储。它通常被称为数据结构服务器,因为键可以包含字符串,哈希,列表,集合,排序集合,位图和超级日志。 TL; DR $ docker run --name redis-cluster -e ALLOW_EMPTY_PASSWORD=yes ...
ansiable redis-cluster
看你写的项目经验,如果你们公司数据量特别大,公司用缓存牛逼,就说Rediscluster,小公司可以说哨兵集群 1.哨兵模式 基本回答:哨兵主要就是启动哨兵(redis特殊)节点,对主节点进行监控,如果半数以上发现ping主...
资源来自pypi官网。 资源全名:redis-py-cluster-1.1.0.tar.gz