redis-集群分片
Redis 分区
分区是分割数据到多个Redis实例的处理过程,因此每个实例只保存key的一个子集。
分区的优势
1.通过利用多台计算机内存的和值,允许我们构造更大的数据库。
2.通过多核和多台计算机,允许我们扩展计算能力;通过多台计算机和网络适配器,允许我们扩展网络带宽。
分区的不足
1.redis的一些特性在分区方面表现的不是很好:
2.涉及多个key的操作通常是不被支持的。举例来说,当两个set映射到不同的redis实例上时,你就不能对这两个set执行交集操作。
3.涉及多个key的redis事务不能使用。
4.当使用分区时,数据处理较为复杂,比如你需要处理多个rdb/aof文件,并且从多个实例和主机备份持久化文件。
5.增加或删除容量也比较复杂。redis集群大多数支持在运行时增加、删除节点的透明数据平衡的能力,但是类似于客户端分区、代理等其他系统则不支持这项特性。然而,一种叫做presharding的技术对此是有帮助的。
分区类型
1.范围分区:最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的Redis实例,比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。
2.哈希分区:另外一种分区方法是hash分区。这对任何key都适用,也无需是object_name:这种形式,像下面描述的一样简单:用一个hash函数将key转换为一个数字,比如使用crc32 hash函数。对key foobar执行crc32(foobar)会输出类似93024922的整数。对这个整数取模,将其转化为0-3之间的数字,就可以将这个整数映射到4个Redis实例中的一个了。93024922 % 4 = 2,就是说key foobar应该被存到R2实例中。注意:取模操作是取除的余数,通常在多种编程语言中用%操作符实现。
下面我尝试在本机(mac,其他系统思路一样)上开启3个redis-service来模拟多机器环境。
1.去官网( https://redis.io/download )上把redis下载了
2.解压之后切cd到第一层目录之后 执行 mark install
3.把redis.conf文件找到,在第一层目录下
4.执行上面之后就能在src文件夹下找到redis-cli和redis-server其他的文件都不用
5.ok 目前是这三个文件 redis-serve/redis-cli/redis.conf
6.现在模拟三个机器(端口6379/6380/6381),只要对应制作三个redis.conf就行,以redis.conf为基础模板改
7.改三个地方(其他部分别动,用redis.conf当模板),得到如下三个配置文件
redis6379.conf
port 6379
pidfile /var/run/redis_6379.pid
dbfilename dump-6379.rdb
redis6380.conf
port 6380
pidfile /var/run/redis_6380.pid
dbfilename dump-6380.rdb
redis6381.conf
port 6381
pidfile /var/run/redis_6381.pid
dbfilename dump-6381.rdb
8.尝试把这三个redis-service 启动起来
redis-server redis6379.conf
redis-server redis6380.conf
redis-server redis6381.conf
9.ps -a | grep redis-server 产看启动结果,如下:
1892 ttys001 0:03.28 redis-server 127.0.0.1:6381
1863 ttys003 0:03.74 redis-server 127.0.0.1:6379
1864 ttys004 0:04.01 redis-server 127.0.0.1:6380
然后是开始分片测试,java的话直接用 JedisShardInfo/ShardedJedisPool 就行,我是用的node,但是没找到相关的库,我手写了下,代码如下:
//npm install redis const redis = require("redis");//开3个redis节点,可以在一个服务器上,也可以分散多个服务器 //PS:如果是自己搭建集群,可以直接一个节点,指向负载均衡的节点上 const client_machine0 = redis.createClient(6379); const client_machine1 = redis.createClient(6380); const client_machine2 = redis.createClient(6381); //造999个用户请求出来 const quaryCount = 999; let cacheDatas = []; for (let index = 0; index < quaryCount; index++) { const nowData = { userId: index, cacheKey: 'k' + index, cacheValue: 'v' + index } cacheDatas.push(nowData); } //分片算法,主流式根据id分区域或者key hash出来 //我这按照id然后mod服务器个数做的 //这里可以自定义算法,一是考虑负载均衡,而是考虑扩展,三是考虑machine死掉怎么救 //运行起来的服务,如果要临时更改,一定一定一定要考虑周全。 //PS:如果是集群的话,这部分逻辑是需要写在集群里,使用者只是访问唯一的地址(通常是某个负载均衡地址)const getMachine = (quaryData) => { let redisMachine = null; switch (quaryData.userId % 3) { case 0: redisMachine = client_machine0; break; case 1: redisMachine = client_machine1; break; case 2: redisMachine = client_machine2; break; default: break; } return redisMachine; }//开始请求模拟 for (let index = 1; index < quaryCount; index++) { const cacheData = cacheDatas[index]; const machine = getMachine(cacheData); if(!machine){ console.log('Error: not find machine!!!'); }else{ machine.set(cacheData.cacheKey, cacheData.cacheValue, redis.print); } }//关闭所有连接 client_machine0.quit(); client_machine1.quit(); client_machine2.quit();关于在线扩容:Redis的作者提出了一种叫做presharding
1.在新机器上启动好对应端口的Redis实例。
2.配置新端口为待迁移端口的从库。
3.待复制完成,与主库完成同步后,切换所有客户端配置到新的从库的端口。
4.配置从库为新的主库。
5.移除老的端口实例。
6.重复上述过程迁移好所有的端口到指定服务器上。
增加高可用的思路就是主从复制
基本命令
成为别人的从库: SLAVEOF host port
取消成为别人的从库 SLAVEOF NO ONE
主从配置更详细的解释跟更多细节,看下这个:
https://www.jianshu.com/p/ba3cc187da9c
总结
以上是生活随笔为你收集整理的redis-集群分片的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 区分docker stack/servi
- 下一篇: Docker 集群 图形化显示 Visu