Redis分片(分区)
Posted 斯温
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis分片(分区)相关的知识,希望对你有一定的参考价值。
分区的概念
分区是分割数据到多个Redis实例的处理过程,因此每个实例只保存key的一个子集。
如果只使用一个redis实例时,其中保存了服务器中全部的缓存数据,这样会有很大风险,如果单台redis服务宕机了将会影响到整个服务。解决的方法就是我们可以采用分片/分区的技术,将原来一台服务器维护的整个缓存,现在换为由多台服务器共同维护内存空间。
分片的实现
说明与分析:
关于redis的安装参照上一篇,默认安装好了redis.
思路:采用在一台主机上实现分片的方式,所以只需要在该主机上配置启动三台redis的实例即可。因为redis默认使用的端口号为6379,所以这里我们分别使用6379、6380以及6381三个端口来实现。
配置:
1. 进入到redis的安装目录下,创建一个shard文件夹,然后将redis的配置文件"redis.conf"复制一份,取名为"redis-6379.conf"(作为6379这台实例的配置文件)。然后将该文件移动到shard文件夹下,再将"redis-6379.conf"复制两份,一个叫"redis-6380.conf"(作为6380这台实例的配置文件),一个叫"redis-6381.conf"(作为6381这台实例的配置文件)。
2. 修改6379这台实例的配置文件,因为端口6379默认就是redis的端口,所以只需要指定该实例的持久化片区(文件)即可。
3. 修改6380实例的配置文件。
- 修改该实例占用的端口为6380
- 修改pid
- 修改dump文件名
4. 修改6381实例的配置文件。
- 修改该实例占用的端口为6381
- 修改pid
- 修改dump文件名
启动与测试:
1. 启动3台redis实例
2. 测试
redis分区有两种方式,对既定的key有不同的方式来选择这个key存放到哪个实例中,也就是说有不同的系统来映射某个key到某个Redis的服务。
- 最简单的分区方式为范围分区,就是映射一定范围的对象到特定的Redis实例。比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。
- 另外一种方式是hash一致算法实现分区,对key值进行hash一致性计算后得到结果,最终将数据保存到某一台redis实例中,具体的hash一致性算法可以自行百度一下。
说明:测试采用junit写的测试方法,方法中定义了一个redis分片的连接池,分别添加用于测试的三个节点实例,然后向redis中增加10个记录并使用Redis Desktop Manager这个工具查看添加结果。
@Test public void test02(){ //定义redis的配置 PoolConfig poolconfig = new PoolConfig(); poolconfig.setMaxTotal(1000); //表示redis的最大连接数——最大1000个线程 poolconfig.setMinIdle(5); //表示最小空闲数量 //定义redis的多个节点机器 List<JedisShardInfo> list = new ArrayList<>(); //为集合添加参数 list.add(new JedisShardInfo("192.168.161.139", 6379)); list.add(new JedisShardInfo("192.168.161.139", 6380)); list.add(new JedisShardInfo("192.168.161.139", 6381)); //定义redis分片连接池 ShardedJedisPool jedisPool = new ShardedJedisPool(poolconfig, list); //获取连接操作redis ShardedJedis shardedJedis = jedisPool.getResource(); //向redis中添加20个记录查看分片结果 for(int i = 0; i < 10; i++){ //增加的记录格式为 key=NUM_i value=i shardedJedis.set("NUM_"+i, ""+i); } }
测试结果:
说明:测试结果发现10个记录中有1个分到了6379区,3个分到了6380区,另外6个分到了6381区,因为是采用记录的key值来进行hash一致性算法来确定记录的存放区域,所以即使重新分区都不会改变记录的存放地址,所以仍然可以根据key值来获取到对应的value值。
分区的不足:
- 分区是多台redis共同作用的,如果其中一台出现了宕机现象,则整个分片都将不能使用,虽然是在一定程度上缓减了内存的压力,但是没有实现高可用。
- 涉及多个key的操作通常是不被支持的。举例来说,当两个set映射到不同的redis实例上时,你就不能对这两个set执行交集操作。
- 涉及多个key的redis事务不能使用。
- 当使用分区时,数据处理较为复杂,比如你需要处理多个rdb/aof文件,并且从多个实例和主机备份持久化文件。
高可用的解决方案:可以采用哨兵机制实现主从复制从而实现高可用。
以上是关于Redis分片(分区)的主要内容,如果未能解决你的问题,请参考以下文章