Redis集群搭建

Redis集群搭建

存在的问题

  • 容量不够,redis如何进行扩容?

  • 并发写操作, redis如何分摊?

  • 另外,主从模式,薪火相传模式,主机宕机,导致ip地址发生变化,应用程序中配置需要修改对应的主机地址、端口等信息(手动修改配置)

  • 在旧的版本中之前通过代理主机请求转发来解决,但是redis3.0中提供了解决方案。就是无中心化集群配置

集群介绍

  • Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N
  • Redis 集群通过分区(partition)来提供一定程度的可用性(availability):即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求

集群如何搭建

  • 创建多个实例的配置文件

  • 开启daemonize -> 指定pid文件名 -> 指定端口 -> 设置log文件名称 -> 设置rdb持久化文件名称 ->appendonly 关掉或者换名字 (关闭aof)

  • 在配置文件中添加集群设置

    • cluster-enabled yes:打开集群模式
    • cluster-config-file nodes-6379.conf:设定节点配置文件名
    • cluster-node-timeout 15000:设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换
    include /myredis/redis.conf
    pidfile “/var/run/redis_6380.pid”
    port 6380
    dbfilename “dump6380.rdb”
    cluster-enabled yes
    cluster-config-file nodes6380.conf
    cluster-node-timeout 15000
    
  • 修改好之后进行配置批量复制与修改

  • 使用vim查找替换修改指定关键字:%s/search/replice

    :%s/6379/6380  
    
  • 启动多个redis服务

    redis-server redisxxx.conf
    
  • 将节点合并为集群,组合之前,请确保所有redis实例启动后,nodes-xxxx.conf文件都生成正常,此处ip不能为127.0.0.1

    redis-cli --cluster create --cluster-replicas 1 10.196.200.164:6380 10.196.200.164:6381 10.196.200.164:6382 10.196.200.164:6390 10.196.200.164:6391 10.196.200.164:6392
    
    >>> Performing hash slots allocation on 6 nodes...
    Master[0] -> Slots 0 - 5460
    Master[1] -> Slots 5461 - 10922
    Master[2] -> Slots 10923 - 16383
    Adding replica 10.196.200.164:6391 to 10.196.200.164:6380
    Adding replica 10.196.200.164:6392 to 10.196.200.164:6381
    Adding replica 10.196.200.164:6390 to 10.196.200.164:6382
    >>> Trying to optimize slaves allocation for anti-affinity
    [WARNING] Some slaves are in the same host as their master
    M: 707f26e97b873e4d617ebcc51f3f95dde40c0954 10.196.200.164:6380
      slots:[0-5460] (5461 slots) master
    M: a26c0f1553d3dc5a4e2753e512ea674022025898 10.196.200.164:6381
      slots:[5461-10922] (5462 slots) master
    M: 33f850f7979feb3aeeecfce0921c0c2d4dbfba80 10.196.200.164:6382
      slots:[10923-16383] (5461 slots) master
    S: 625e48f4a5ffec904728102b1dcceb60e70a9a95 10.196.200.164:6390
      replicates a26c0f1553d3dc5a4e2753e512ea674022025898
    S: 4b7d3ffb21836be12ec0372351909b7505dc3368 10.196.200.164:6391
      replicates 33f850f7979feb3aeeecfce0921c0c2d4dbfba80
    S: 7e014644611a9e088f84a18ec2aead3f56bf6c3f 10.196.200.164:6392
      replicates 707f26e97b873e4d617ebcc51f3f95dde40c0954
    Can I set the above configuration? (type ‘yes’ to accept): yes
    
  • –replicas 1 采用最简单的方式配置集群,一台主机,一台从机,正好三组

登录集群

  • 普通方式登录:可能直接进入读主机,存储数据时,会出现MOVED重定向操作。所以,应该以集群方式登录

  • 采用集群策略连接-c,设置数据会自动切换到相应的写主机

    redis-cli -c -p 6380
    

查看集群信息

  • cluster nodes

    root@vmware:/usr/bin# redis-cli -c -p 6380
    127.0.0.1:6380> cluster nodes
    707f26e97b873e4d617ebcc51f3f95dde40c0954 10.196.200.164:6380@16380 myself,master - 0 1656998697000 1 connected 0-5460
    4b7d3ffb21836be12ec0372351909b7505dc3368 10.196.200.164:6391@16391 slave 33f850f7979feb3aeeecfce0921c0c2d4dbfba80 0 1656998699105 3 connected
    33f850f7979feb3aeeecfce0921c0c2d4dbfba80 10.196.200.164:6382@16382 master - 0 1656998698000 3 connected 10923-16383
    7e014644611a9e088f84a18ec2aead3f56bf6c3f 10.196.200.164:6392@16392 slave 707f26e97b873e4d617ebcc51f3f95dde40c0954 0 1656998698000 1 connected
    625e48f4a5ffec904728102b1dcceb60e70a9a95 10.196.200.164:6390@16390 slave a26c0f1553d3dc5a4e2753e512ea674022025898 0 1656998700112 2 connected
    a26c0f1553d3dc5a4e2753e512ea674022025898 10.196.200.164:6381@16381 master - 0 1656998699000 2 connected 5461-10922
    
  • salve后面是master的id

节点分配原则

  • 分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上
  • 多个主数据库不会同时宕机,主库与从库不会同时宕机,主库宕机后从库变为主库,保障高可用

插槽(Slot)介绍

  • 一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个

  • Redis集群会将16384个插槽均匀分配到每个节点

  • 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和,类似于计算hash得到key的存储位置

  • 客户端可以连接集群中任意一个Redis 实例,发送读写命令,如果当前Redis 实例收到不是自己负责的Slot的请求时,会将该slot所在的正确的Redis 实例地址返回给客户端,客户端收到后,自动将原请求重新发到这个新地址,自动操作,外部透明

    Redirected to slot [12706] located at 10.196.200.164:6382   //自动重定向
    OK
    
  • 但是同时设置多个值会出现这种问题:

    mset k2 v2 k3 v3
    (error) CROSSSLOT Keys in request don’t hash to the same slot
    
  • 解决方法:可以通过{}来定义组的概念,从而使key中{}内相同内容的键值对放到一个slot中去,根据组名计算slot的值

    mset k1{g1} v1 k2{g1} v2
    
  • 查询插槽中的值

    CLUSTER GETKEYSINSLOT  返回 count 个 slot 槽中的键
    

故障恢复

  • 当主节点下线,从节点会自动升为主节点
  • 主节点恢复后将作为从节点继续运行
  • 如果所有某一段插槽的主从节点都宕掉,redis服务是否还能继续?
    • cluster-require-full-coverage 为yes ,整个集群都挂掉
    • cluster-require-full-coverage 为no ,那么,该插槽数据全都不能使用,也无法存储

优缺点

优点:

  • 实现扩容
  • 分摊压力
  • 无中心配置相对简单

缺点

  • 多键操作是不被支持的
  • 多键的Redis事务是不被支持的,lua脚本不被支持
  • 由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片的方案想要迁移至redis cluster,需要整体迁移而不是逐步过渡,复杂度较大

你可能感兴趣的