• Redis集群高可用


    Redis集群的概念:

      RedisCluster是redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的需求,当一个服务挂了可以快速的切换到另外一个服务,当遇到单机内存、并发等瓶颈时,可使用此方案来解决这些问题

    一、分布式数据库概念

    1. 分布式数据库把整个数据按分区规则映射到多个节点,即把数据划分到多个节点上,每个节点负责整体数据的一个子集。比如我们库有900条用户数据,有3个redis节点,将900条分成3份,分别存入到3个redis节点

    2. 分区规则:

       常见的分区规则哈希分区和顺序分区,redis集群使用了哈希分区,顺序分区暂用不到,不做具体说明;

       rediscluster采用了哈希分区的“虚拟槽分区”方式(哈希分区分节点取余、一致性哈希分区和虚拟槽分区),其它两种也不做介绍,有兴趣可以百度了解一下

    3. 虚拟槽分区(槽:slot)

       RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]&16383)映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据

       哈希函数: Hash()=CRC16[key]&16383 按位与

       槽与节点的关系如下

    redis用虚拟槽分区原因:解耦数据与节点关系,节点自身维护槽映射关系,分布式存储

    4. redisCluster的特点:

     
     3、集群优缺点

    5. redisCluster的缺陷:

    a,键的批量操作支持有限,比如mset, mget,如果多个键映射在不同的槽,就不支持了

    b,键事务支持有限,当多个key分布在不同节点时无法使用事务,同一节点是支持事务

    c,键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点

    d,不支持多数据库,只有0,select 0

    e,复制结构只支持单层结构,不支持树型结构。  

    二、集群环境搭建

    部署结构图:6389为6379的从节点,6390为6380的从节点,6391为6381的从节点

    1./opt目录下,下载redis5.0.9版本

    yum install gcc-c++
    yum install -y gcc make
    cd /opt
    wget http://download.redis.io/releases/redis-5.0.9.tar.gz tar -zxf redis-5.0.9.tar.gz
    cd redis-5.0.9/
    make

    1.在/opt目录下将下载的redis复制5份,以作集群使用

    2. 分别修改6379、 6380、 6381、 6389、 6390、 6391配置文件

    以6379的配置为例(修改红色部分),数据存储默认dir ./,会造成存储位置不固定,最好修改成自己的路径:

    #bind 127.0.0.1
    protected-mode no port 6379
    tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes supervised no pidfile /var/run/redis.pid loglevel notice logfile "" databases 16 always-show-logo yes save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /opt/redis-1/data/ slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no slave-lazy-flush no appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble no lua-time-limit 5000 cluster-enabled yes slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes

    其它节点的配置和这个一致,改端口即可

    3. 配置完后,启动6个redis服务(启动前保证每个redis没有数据存在,如果有请删除,要不然会启动失败)

    /opt/redis-1/src/redis-server /opt/redis-1/redis.conf 
    /opt/redis-2/src/redis-server /opt/redis-2/redis.conf 
    /opt/redis-3/src/redis-server /opt/redis-3/redis.conf 
    /opt/redis-4/src/redis-server /opt/redis-4/redis.conf 
    /opt/redis-5/src/redis-server /opt/redis-5/redis.conf 
    /opt/redis-6/src/redis-server /opt/redis-6/redis.conf 

    4.防火墙开放端口,以6379为例

    firewall-cmd --zone=public --add-port=6379/tcp --permanent
    systemctl stop firewalld.service
    systemctl start firewalld.service 

     此时远程就可以访问到我们的redis了,下面就是构建集群。

    5.构建集群

    这个版本支持集群,不需要安装ruby和gem

    进入其中一个redis的src目录

    cd /opt/redis-1/src
    ./redis-cli --cluster create 192.168.222.157:6379 192.168.222.157:6380 192.168.222.157:6381 192.168.222.157:6389 192.168.222.157:6390 192.168.222.157:6391 --cluster-replicas 1

    我们可以使用cluster info和cluster nodes查看集群情况(要在客户端下使用   redis-cli -c -p port)

    cluster info
    cluster nodes

     集群中的节点数目和主从关系和我们开头预期的是一致的。

    至此集群构建成功!

    6.编程测试集群

    引入redis的依赖

    <!-- redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <!-- 如果使用Lettuce作为连接池,需要引入commons-pool2包,否则会报错bean注入失败 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
            <!-- Jedis 客户端 -->
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
            </dependency>

    yml添加redis配置

      redis:
        timeout: 6000  # 连接超时时间(毫秒)默认是2000ms
        lettuce:
          pool:
            max-active: 200  # 连接池最大连接数(使用负值表示没有限制)
            max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
            max-idle: 100 # 连接池中的最大空闲连接
            min-idle: 50 # 连接池中的最小空闲连接
          shutdown-timeout: 500
        cluster:   #集群模式
          nodes:
            - 192.168.222.157:6379
            - 192.168.222.157:6380
            - 192.168.222.157:6381
            - 192.168.222.157:6389
            - 192.168.222.157:6390
            - 192.168.222.157:6391
          max-redirects: 3    # 获取失败 最大重定向次数

    向redis写100条数据

    @Slf4j
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ShaobingApplicationTests {
    
        @Resource
        private RedisTemplate redisTemplate;
    
        @Test
        public void testStringRedisTemplate() throws InterruptedException {
            for (int i = 0; i < 100; i++) {
                redisTemplate.opsForValue().set(String.valueOf(i + 1), i + 1);
            }
        }
    }

    看下存储效果

     可以看出100条数据均匀分布在3个节点上,每个节点主从也是保持一致

    7.redis服务操作命令

    复制代码
    systemctl start redis.service #启动redis服务
    
    systemctl stop redis.service #停止redis服务
    
    systemctl restart redis.service #重新启动服务
    
    systemctl status redis.service #查看服务当前状态
    
    systemctl enable redis.service #设置开机自启动
    
    systemctl disable redis.service #停止开机自启动
    三、集群客户端命令(redis-cli -c -p port)
    集群
    cluster info :打印集群的信息
    cluster nodes :列出集群当前已知的所有节点( node),以及这些节点的相关信息。
    节点
    cluster meet <ip> <port> :将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
    cluster forget <node_id> :从集群中移除 node_id 指定的节点。
    cluster replicate <node_id> :将当前节点设置为 node_id 指定的节点的从节点。
    cluster saveconfig :将节点的配置文件保存到硬盘里面。
    槽(slot)
    cluster addslots <slot> [slot ...] :将一个或多个槽( slot)指派( assign)给当前节点。
    cluster delslots <slot> [slot ...] :移除一个或多个槽对当前节点的指派。
    cluster flushslots :移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
    cluster setslot <slot> node <node_id> :将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给
    另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
    cluster setslot <slot> migrating <node_id> :将本节点的槽 slot 迁移到 node_id 指定的节点中。
    cluster setslot <slot> importing <node_id> :从 node_id 指定的节点中导入槽 slot 到本节点。
    cluster setslot <slot> stable :取消对槽 slot 的导入( import)或者迁移( migrate)。

    cluster keyslot <key> :计算键 key 应该被放置在哪个槽上。
    cluster countkeysinslot <slot> :返回槽 slot 目前包含的键值对数量。
    cluster getkeysinslot <slot> <count> :返回 count 个 slot 槽中的键  
    四、集群中Master的下线及恢复
    1、Master下线后,其对应的Slaver节点会自动变为Master节点(下线6381主节点)
    2、原来的Master重启后变成Slaver节点,并是原来Master节点的Slaver节点
  • 相关阅读:
    Linux内核之 I/O多路复用
    Linux内核之 页高速缓存与页回写
    Linux内核之 块I/O层及I/O调度
    Linux内核之 文件I/O
    C++雾中风景15:聊聊让人抓狂的Name Mangling
    音频数据增强及python实现
    深度学习中“过拟合”的产生原因和解决方法
    资料-资源(不定期更新)
    论文翻译:2020_Acoustic Echo Cancellation Challenge Datasets And Testingframework
    语音信号处理概念
  • 原文地址:https://www.cnblogs.com/wiliamzhao/p/13680554.html
Copyright © 2020-2023  润新知