docker搭建redis三主三从哈希槽分布式存储+CAdvistor+InfluxDB+Granfana

docker搭建redis三主三从哈希槽分布式存储+CAdvistor+InfluxDB+Granfana

保姆级教程!!

1~2亿条数据需要缓存,如何实现这个存储?

单机单台必然不可能,绝对是使用分布式存储:

  • 哈希取余分区:2亿条记录就是2亿个k,v,我们单机不行必须要分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式:

    hash(key) % N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。

    • 优点:简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。

    • 缺点:原来规划好的节点,进行扩容或者缩容就比较麻烦了额,不管扩缩,每次数据变动导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化:Hash(key)/3会变成Hash(key) /?。此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。

      某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。

    • 一致性哈希算法分区:将所有的存储节点排列在收尾相接的Hash环上,每个key在计算Hash后会顺时针找到临近的存储节点存放。

      而当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后续节点。

      • 优点:加入和删除节点只影响哈希环中顺时针方向的相邻的节点,对其他节点无影响。
      • 缺点:数据的分布和节点的位置有关,因为这些节点不是均匀的分布在哈希环上的,所以数据在进行存储时达不到均匀分布的效果。
      • 哈希槽分区:解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。

        槽解决的是粒度问题,相当于把粒度变大了,这样便于数据移动。

        哈希解决的是映射问题,使用key的哈希值来计算所在的槽,便于数据分配。

        一个集群只能有16384个槽,编号0-16383(0-2^14-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key求哈希值,然后对16384取余,余数是几key就落入对应的槽里。slot = CRC16(key) % 16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。

        正式开始搭建redis三主三从(本文采用docker容器搭建方式)

        • 确认docker启动
          systemctl status docker
          
          • pull redis镜像,本文采用版本6.0.8
            docker pull redis:6.0.8
            
            • 新建6个docker容器redis实例

              • docker run -d --name redis-node1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
                docker run -d --name redis-node2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
                docker run -d --name redis-node3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
                docker run -d --name redis-node4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
                docker run -d --name redis-node5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
                docker run -d --name redis-node6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
                
              • 命令分布解释

                docker run   #创建并运行docker容器实例
                --name redis-node1   #容器名字
                --net host  #使用宿主机的IP和端口,默认
                --privileged=true  #获取宿主机root用户权限
                -v /data/redis/share/redis-node-6:/data  #容器数据卷(持久化用),宿主机:docker内部地址
                redis:6.0.8  #redis镜像和版本号
                --cluster-enable yes  #开启redis集群
                --appendonly yes  #开启持久化
                --port 6386  #redis端口号
                
              • 以redis-node1为切入口,为6台机器构建集群关系

                docker exec -it redis-node1 bash  #进入redis-node1容器
                
                • 构建主从关系
                  redis-cli --cluster create 192.168.184.90:6381 192.168.184.90:6382 192.168.184.90:6383 192.168.184.90:6384 192.168.184.90:6385 192.168.184.90:6386 --cluster-replicas 1
                  #--cluster-replicas 1 表示为每个master创建一个slave节点
                  #这里要注意自己的真实ip地址
                  
                  • 一切OK的话,3主3从搞定
                  • 链接进入6381作为切入点,查看集群情况,-c表示以集群的形式接入
                    • 可以看到三主为node1、node2、node3,其对应的从节点分别为node4、node5、node6

                    • 当主节点宕机后,从节点会自己升级为主节点,而原先的主节点修复后重新加入集群后变为新的从节点,这里不再多做演示

                      容器监控三剑客CIG

                      CAdvisor监控收集+InfluxDB存储数据+Granfana展示图表

                      • 创建CIG使用的目录
                        • 创建三件套组合的compose文件
                          [root@localhost cig]# vim docker-compose.yml
                          version: '3.1'
                          volumes:
                            grafana_data: {}
                          services:
                           influxdb:
                            image: tutum/influxdb:0.9
                            restart: always
                            environment:
                              - PRE_CREATE_DB=cadvisor
                            ports:
                              - "8083:8083"
                              - "8086:8086"
                            volumes:
                              - ./data/influxdb:/data
                           cadvisor:
                            image: google/cadvisor
                            links:
                              - influxdb:influxsrv
                            command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086
                            restart: always
                            ports:
                              - "8080:8080"
                            volumes:
                              - /:/rootfs:ro
                              - /var/run:/var/run:rw
                              - /sys:/sys:ro
                              - /var/lib/docker/:/var/lib/docker:ro
                           grafana:
                            user: "104"
                            image: grafana/grafana
                            user: "104"
                            restart: always
                            links:
                              - influxdb:influxsrv
                            ports:
                              - "3000:3000"
                            volumes:
                              - grafana_data:/var/lib/grafana
                            environment:
                              - HTTP_USER=admin
                              - HTTP_PASS=admin
                              - INFLUXDB_HOST=influxsrv
                              - INFLUXDB_PORT=8086
                              - INFLUXDB_NAME=cadvisor
                              - INFLUXDB_USER=root
                              - INFLUXDB_PASS=root
                          
                          • 启动docker-compose文件
                            [root@localhost cig]# docker-compose up
                            
                            • 查看三个服务容器是否启动
                              [root@localhost ~]# docker ps
                              
                              • 浏览CAdvistor收集服务,http://IP:8080

                                第一次访问较慢,CAdvistor也有基础的图形展示功能,这里主要用它来做数据采集

                                • 浏览InfluxDB存储服务,http://IP:8083
                                  • 浏览Grafana模板展示服务,http://IP:3000

                                    • IP+端口的方式访问,默认账户密码admin/admin,登录后会强制要求修改密码

                                    • 配置数据源

                                    • 选择influxdb数据源

                                    • 配置细节

                                    • 配置面板panel

                                    • 到这里cAdvisor+InfluxDB+Grafana容器监控系统就部署完成了