欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

redis-集群分片

发布时间:2025/6/17 编程问答 7 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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-集群分片的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。