精华内容
下载资源
问答
  • redis架构图

    2018-12-25 15:06:25
    redis是一个key-value存储系统。和Memcached类似,它支持存储value类型相对更多,...区别redis会周期性把更新数据写入磁盘或者把修改操作写入追加记录文件,并且在此基础上实现了master-slave(主从)同步。
  • 一、Redis集群架构1、Redis集群架构图蓝色Redis集群中每个node节点,节点之间通过ping 命令,测试相互是否连接正常,普通集群没有主从区分,连接任何一个节点操作,都可以转发到其他任意一个节点。1、Redis ...

    7a9c9333ea9648cd88c81330f710df01.png

    Redis的安装和部署(Linux)一文中详细介绍了在Linux环境中搭建Redis服务,本文将介绍关于Redis分布式 集群搭建细节。一、Redis集群架构1、Redis集群架构图

    66e54c92adc37a4d7437f76b35aa6e8f.png

    蓝色的为Redis集群中的每个node节点,节点之间通过ping 命令,测试相互是否连接正常,普通集群没有主从区分,连接任何一个节点操作,都可以转发到其他任意一个节点。1、Redis 容错机制每Redis提供了节点之间相互发送的ping命令,用于测试每个节点的健康状态,集群中连接正常的节点接收到其他节点发送的ping命令时,会返回一个pong字符串。Redis投票机制:如果一个节点A给B发送ping没有得到pong返回,那么A就会通知其他节点再次给B发送ping,如果集群中超过一半的节点给B发送ping都没有得到返回,那么B就被坐实game over了,所以为了避免单点故障,一般都会为Redis的每个节点提供一个备份节点,B节点挂掉了立马启动B的备份节点服务器。2、Redis 集群存储原理每个节点上的数据都不一样,(一样就是主备了)把数据都分散存放到各个节点上进行存储。如何确定哪些类型数据存入哪个节点呢?Redis中槽slot就用于圈定当前节点的存储范围,分散存储使用hash算法,确定什么值放到哪个槽里。 所以在创建Redis集群时,会首先为每个节点创建槽容量,例如从1~2000,指定数据存储区域。3、Redis 持久化机制Redis提供了2中数据持久化方式:
    • Snapshotting:定时的将Redis内存的当前状态保存到RDB文件中,持久化到硬盘。
    • AOF(append-only file):将所有的command操作保存到aof文件中,AOP使得同步频率很高,数据即便丢失,粒度也很小,但性能上有所牺牲。默认数据持久化会2s同步一次,也可以进行配置改变同步频率。
    二、Redis集群搭建现在开始搭建具有3各节点和3个备份节点的Redis cluster。端口分别从7001-7006,因为测试机内存的原因,搭建一个使用6个Redis实例搭建一个伪分布式集群。 1、搭建集群所需环境
    • 使用yum install ruby安装Ruby,因为redis中创建集群的脚本是以rb结尾的ruby文件(下图可见该rb文件)。使用ruby -v查看ruby是否安装成功。

    1dd1f30adff7e6ba65df9bd7531c2030.png

    • 使用 yum install rubygems安装RubyGems-Ruby组件的打包系统,用于管理Ruby程序包。
    2、创建6个Redis实例
    • 将redis的解压包中的bin文件件均拷贝到新创建的redis-cluster(含有redis-trib.rb文件)的redis01文件中

    aace36915e5b4b42eb7c54ccbb210817.png

    • 修改redis01的redis.conf文件,修改端口号和cluster-enable属性

    e237904afe0e7115f7db82fb2abd0db8.png

    • 依次拷贝redis01为redis02-redis06,修改端口号

    35d921455070db98035882247911f6d8.png

    • 编写一个sh脚本,一次性启动6个Redis实例

    0fdd952b245b67bcdc7582bdc280e494.png

    • 执行sh脚本,启动redis节点,并查看Redis实例启动情况

    d77440f5e0459f0cacd0bccd69fa1f7c.png

    • 执行redis-trib.rb脚本,创建集群。
    ./redis-trib.rb create --replicas 1 192.168.132.128:7001 192.168.132.128:7002 192.168.132.128:7003 192.168.132.128:7004 192.168.132.128:7005  192.168.132.128:7006

    ac04bd8e938345356b1e421baae5eba3.png

    在集群的创建日志信息中可以发现,使用hash 创建slots,master节点为01.02.03 ,剩余3个用于做备机节点,并显示了主从对应关系以及每个节点槽范围信息。三、集群测试
    • 使用任意一个节点客户端登陆 主要加上 -c参数表示用于集群连接
    • 任意执行一个set命令,节点间会自动转发,将set的值保存到对应的节点slot中。 

    544bd0d9496210346bcb90b989b5694e.png

        集群搭建成功。四、总结建成功。在创建集群时,笔者出现一个redis节点拒绝连接的错误,以至于集群创建失败。

    407ffa64f49173d60080d60d9fbf4bf7.png

    经过反复排查发现是自己原来安装的redis进行了权限设置,为方便了方便测试,于是选择取消该权限设置。来源:https://blog.csdn.net/Daybreak1209/article/details/51493265

    ·END·

    PHP开源社区进阶·提升·涨薪3dcab6a5882cc0ead58761efea3eea88.png
    展开全文
  • 这道面试题主要考Redis常用的架构模式的理解,常用几种架构模式有:1.单机模式Redis单机版架构图特点:简单问题:内存有限有单点故障风险,无法高可用处理能力有限2.主从模式Redis主从模式架构图Redis 的复制...

    这道面试题主要考Redis常用的架构模式的理解,常用几种架构模式有:

    1.单机模式

    a03a9d309ff19997e94087d1c575ca85.png

    Redis单机版架构图

    特点:简单

    问题:

    1. 内存有限
    2. 有单点故障风险,无法高可用
    3. 处理能力有限

    2.主从模式

    3a527f5d11d4f441d3f17c1304e3f107.png

    Redis主从模式架构图

    Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。

    特点:

    1. 主从数据保持同步
    2. 可降低Master读的压力

    问题:

    1. 没有解决高可用
    2. 没有解决Master写入的压力

    3.Redis sentinel 哨兵模式

    5bc7d9736a2f7d0f8267a0b47fff98b4.png

    Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。它有三个特性:

    特点:

    1. 保证高可用
    2. 监控各个环节
    3. 自动故障迁移

    问题:

    1. 主从模式,切换需要时间丢数据
    2. 没有解决 master 写的压力

    4.集群代理模式

    97b75993961ae57adb40773037eaafd5.png

    Redis集群代理模式架构图

    Twemproxy 是一个 Twitter 开源的一个 redis 和 memcache 快速/轻量级代理服务器; Twemproxy 是一个快速的单线程代理程序,支持 Memcached ASCII 协议和 redis 协议。

    特点:

    1. 支持多种 hash 算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins
    2. 支持失败节点自动删除
    3. 后端 Sharding 分片逻辑对业务透明,业务方的读写方式和操作单个 Redis 一致

    问题:

    1. 需要维护代理的高可用

    5.集群直连型

    d6d44d77b4f00aaec36eaea8a8e4f92d.png

    从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

    特点:

    1. 无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。
    2. 数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
    3. 可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
    4. 高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本
    5. 实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。

    问题:

    1. 资源隔离性较差,容易出现相互影响的情况。
    2. 数据通过异步复制,不保证数据的强一致性
    展开全文
  • 文章目录前言一、基于Sentinel的Redis HA架构二、搭建步骤2.1 redis 源码编译2.2 Redis主从结构2.3 Redis Sentinels2.4 测试三、使用JedisSentinelPool操作Redis 前言 Redis Sentinel(哨兵)是官网推荐的redis高...


    前言

    Redis Sentinel(哨兵)是官网推荐的redis高可用解决方案。Sentinel的稳定版自Redis 2.8开始正式发布。


    一、基于Sentinel的Redis HA架构

    基于Sentinel的Redis HA架构
    常见Redis HA结构,如上图,包含一主、两从、三哨兵,是Reids主从模式+哨兵集群的组合。其中:

    • Redis Master(主节点):负责处理redis读、写请求;
    • Redis Slave(从节点):负责从redis主节点同步数据,保持与主节点的数据同步;处理redis读请求;
    • Sentinel(哨兵):负责监管整个redis主从结构;

    二、搭建步骤

    2.1 Redis 源码编译

    从 https://redis.io/download 下载最新版 Redis 6.0.9,需要自行编译。下载解压后,按照官网提示的安装步骤进行操作,对源码进行编译。
    redis编译步骤

    2.2 Redis主从结构

    编译完成后,进入redis-6.0.9解压、编译目录,将配置文件redis.conf复制三份,分别命名、修改以下配置。

    1. redis-master.conf 主节点配置

      #......
      # Accept connections on the specified port, default is 6379 (IANA #815344).
      # If port 0 is specified Redis will not listen on a TCP socket.
      port 6380
      
      # If a pid file is specified, Redis writes it where specified at startup
      # and removes it at exit.
      #
      # When the server runs non daemonized, no pid file is created if none is
      # specified in the configuration. When the server is daemonized, the pid file
      # is used even if not specified, defaulting to "/var/run/redis.pid".
      #
      # Creating a pid file is best effort: if Redis is not able to create it
      # nothing bad happens, the server will start and run normally.
      pidfile /var/run/redis_6380.pid
      
    2. redis-slave1.conf,从节点1配置,将主节点设置为6380。

      #......
      # Accept connections on the specified port, default is 6379 (IANA #815344).
      # If port 0 is specified Redis will not listen on a TCP socket.
      port 6381
      
      # If a pid file is specified, Redis writes it where specified at startup
      # and removes it at exit.
      #
      # When the server runs non daemonized, no pid file is created if none is
      # specified in the configuration. When the server is daemonized, the pid file
      # is used even if not specified, defaulting to "/var/run/redis.pid".
      #
      # Creating a pid file is best effort: if Redis is not able to create it
      # nothing bad happens, the server will start and run normally.
      pidfile /var/run/redis_6381.pid
      
      # Master-Replica replication. Use replicaof to make a Redis instance a copy of
      # another Redis server. A few things to understand ASAP about Redis replication.
      #
      #   +------------------+      +---------------+
      #   |      Master      | ---> |    Replica    |
      #   | (receive writes) |      |  (exact copy) |
      #   +------------------+      +---------------+
      #
      # 1) Redis replication is asynchronous, but you can configure a master to
      #    stop accepting writes if it appears to be not connected with at least
      #    a given number of replicas.
      # 2) Redis replicas are able to perform a partial resynchronization with the
      #    master if the replication link is lost for a relatively small amount of
      #    time. You may want to configure the replication backlog size (see the next
      #    sections of this file) with a sensible value depending on your needs.
      # 3) Replication is automatic and does not need user intervention. After a
      #    network partition replicas automatically try to reconnect to masters
      #    and resynchronize with them.
      #
      replicaof 127.0.0.1 6380
      
    3. redis-slave2.conf,从节点2配置,将主节点设置为6380。

      port 6382
      
      pidfile /var/run/redis_6382.pid
      
      replicaof 127.0.0.1 6380
      

    在redis-6.0.9目录下,依次通过下述命令来启动redis节点。

    src/redis-server redis-master.conf
    src/redis-server redis-slave1.conf

    从redis的启动日志中,可以看到redis从节点连接到主节点、同步数据的相关情况。

    2.3 Redis Sentinels

    在redis-6.0.9目录下,将sentinel.conf配置复制三份,分别重命名、修改以下配置。

    1. sentinel_26380.conf

      # *** IMPORTANT ***
      #
      # By default Sentinel will not be reachable from interfaces different than
      # localhost, either use the 'bind' directive to bind to a list of network
      # interfaces, or disable protected mode with "protected-mode no" by
      # adding it to this configuration file.
      #
      # Before doing that MAKE SURE the instance is protected from the outside
      # world via firewalling or other means.
      #
      # For example you may use one of the following:
      #
      # bind 127.0.0.1 192.168.1.1
      #
      # protected-mode no
      
      # port <sentinel-port>
      # The port that this sentinel instance will run on
      port 26380
      
      # When running daemonized, Redis Sentinel writes a pid file in
      # /var/run/redis-sentinel.pid by default. You can specify a custom pid file
      # location here.
      pidfile /var/run/redis-sentinel-26380.pid
      
      # sentinel monitor <master-name> <ip> <redis-port> <quorum>
      #
      # Tells Sentinel to monitor this master, and to consider it in O_DOWN
      # (Objectively Down) state only if at least <quorum> sentinels agree.
      #
      # Note that whatever is the ODOWN quorum, a Sentinel will require to
      # be elected by the majority of the known Sentinels in order to
      # start a failover, so no failover can be performed in minority.
      #
      # Replicas are auto-discovered, so you don't need to specify replicas in
      # any way. Sentinel itself will rewrite this configuration file adding
      # the replicas using additional configuration options.
      # Also note that the configuration file is rewritten when a
      # replica is promoted to master.
      #
      # Note: master name should not include special characters or spaces.
      # The valid charset is A-z 0-9 and the three characters ".-_".
      sentinel monitor mymaster 127.0.0.1 6380 2
      

      告诉当前Sentinel,要监视的redis主节点为:127.0.0.1 6380。

      通过src/redis-sentinel sentinel_26380.conf 来启动Sentinel。

      > src/redis-sentinel sentinel_26380.conf 
      1043:X 15 Nov 2020 10:59:52.528 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
      1043:X 15 Nov 2020 10:59:52.528 # Redis version=6.0.9, bits=64, commit=00000000, modified=0, pid=1043, just started
      1043:X 15 Nov 2020 10:59:52.528 # Configuration loaded
      1043:X 15 Nov 2020 10:59:52.529 * Increased maximum number of open files to 10032 (it was originally set to 2560).
                      _._                                                  
                 _.-``__ ''-._                                             
            _.-``    `.  `_.  ''-._           Redis 6.0.9 (00000000/0) 64 bit
        .-`` .-```.  ```\/    _.,_ ''-._                                   
       (    '      ,       .-`  | `,    )     Running in sentinel mode
       |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26380
       |    `-._   `._    /     _.-'    |     PID: 1043
        `-._    `-._  `-./  _.-'    _.-'                                   
       |`-._`-._    `-.__.-'    _.-'_.-'|                                  
       |    `-._`-._        _.-'_.-'    |           http://redis.io        
        `-._    `-._`-.__.-'_.-'    _.-'                                   
       |`-._`-._    `-.__.-'    _.-'_.-'|                                  
       |    `-._`-._        _.-'_.-'    |                                  
        `-._    `-._`-.__.-'_.-'    _.-'                                   
            `-._    `-.__.-'    _.-'                                       
                `-._        _.-'                                           
                    `-.__.-'                                               
      
      1043:X 15 Nov 2020 10:59:52.531 # Sentinel ID is 294d622af53ec541a775385baf7cdf99a34f3163
      1043:X 15 Nov 2020 10:59:52.531 # +monitor master mymaster 127.0.0.1 6380 quorum 2
      1043:X 15 Nov 2020 10:59:52.532 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
      1043:X 15 Nov 2020 10:59:52.533 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
      

      从日志中可以看到,虽然Sentinel配置文件中仅设置了redis主节点的ip、端口,但Sentinel仍然能通过主节点来获取其从节点(6381、6382)的信息。

    2. sentinel_26381.conf

      port 26381
      
      pidfile /var/run/redis-sentinel-26381.pid
      
      # 监视同一主节点
      sentinel monitor mymaster 127.0.0.1 6380 2
      

      启动Sentinel。

      > src/redis-sentinel sentinel_26381.conf 
      1089:X 15 Nov 2020 11:09:41.782 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
      1089:X 15 Nov 2020 11:09:41.782 # Redis version=6.0.9, bits=64, commit=00000000, modified=0, pid=1089, just started
      1089:X 15 Nov 2020 11:09:41.782 # Configuration loaded
      1089:X 15 Nov 2020 11:09:41.783 * Increased maximum number of open files to 10032 (it was originally set to 2560).
                      _._                                                  
                 _.-``__ ''-._                                             
            _.-``    `.  `_.  ''-._           Redis 6.0.9 (00000000/0) 64 bit
        .-`` .-```.  ```\/    _.,_ ''-._                                   
       (    '      ,       .-`  | `,    )     Running in sentinel mode
       |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26381
       |    `-._   `._    /     _.-'    |     PID: 1089
        `-._    `-._  `-./  _.-'    _.-'                                   
       |`-._`-._    `-.__.-'    _.-'_.-'|                                  
       |    `-._`-._        _.-'_.-'    |           http://redis.io        
        `-._    `-._`-.__.-'_.-'    _.-'                                   
       |`-._`-._    `-.__.-'    _.-'_.-'|                                  
       |    `-._`-._        _.-'_.-'    |                                  
        `-._    `-._`-.__.-'_.-'    _.-'                                   
            `-._    `-.__.-'    _.-'                                       
                `-._        _.-'                                           
                    `-.__.-'                                               
      
      1089:X 15 Nov 2020 11:09:41.786 # Sentinel ID is 7a8ec851d30638c286fbfcb916d3b3080070cbdc
      1089:X 15 Nov 2020 11:09:41.786 # +monitor master mymaster 127.0.0.1 6380 quorum 2
      1089:X 15 Nov 2020 11:09:41.786 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
      1089:X 15 Nov 2020 11:09:41.787 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
      1089:X 15 Nov 2020 11:09:42.235 * +sentinel sentinel 294d622af53ec541a775385baf7cdf99a34f3163 127.0.0.1 26380 @ mymaster 127.0.0.1 6380
      

      从启动日志中,可以看到当前启动的Sentinel也能够发现之前已启动的26380 Sentinel。

    3. sentinel_26382.conf

      port 26382
      
      pidfile /var/run/redis-sentinel-26382.pid
      # 监视同一主节点
      sentinel monitor mymaster 127.0.0.1 6380 2
      

    2.4 测试

    至此,基于Sentinel的Redis HA搭建完成,来测试下功能,将当前redis master节点宕机。

    关闭master节点 6380。

    ^C
    699:signal-handler (1605441212) Received SIGINT scheduling shutdown...
    699:M 15 Nov 2020 19:53:32.112 # User requested shutdown...
    699:M 15 Nov 2020 19:53:32.112 * Saving the final RDB snapshot before exiting.
    699:M 15 Nov 2020 19:53:32.119 * DB saved on disk
    699:M 15 Nov 2020 19:53:32.119 * Removing the pid file.
    699:M 15 Nov 2020 19:53:32.120 # Redis is now ready to exit, bye bye...
    

    master节点19:53:32宕机。

    查看Sentinel日志。

    1089:X 15 Nov 2020 19:42:32.956 # -tilt #tilt mode exited
    1089:X 15 Nov 2020 19:54:02.196 # +sdown master mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:02.248 # +odown master mymaster 127.0.0.1 6380 #quorum 3/2
    1089:X 15 Nov 2020 19:54:02.249 # +new-epoch 1
    1089:X 15 Nov 2020 19:54:02.249 # +try-failover master mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:02.254 # +vote-for-leader 7a8ec851d30638c286fbfcb916d3b3080070cbdc 1
    1089:X 15 Nov 2020 19:54:02.257 # 294d622af53ec541a775385baf7cdf99a34f3163 voted for 7a8ec851d30638c286fbfcb916d3b3080070cbdc 1
    1089:X 15 Nov 2020 19:54:02.257 # dd6847a566933f15bb8bb04be7f3504f2c00071c voted for 7a8ec851d30638c286fbfcb916d3b3080070cbdc 1
    1089:X 15 Nov 2020 19:54:02.313 # +elected-leader master mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:02.313 # +failover-state-select-slave master mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:02.377 # +selected-slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:02.377 * +failover-state-send-slaveof-noone slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:02.432 * +failover-state-wait-promotion slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:03.062 # +promoted-slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:03.062 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:03.130 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:03.402 # -odown master mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:04.071 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:04.071 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:04.146 # +failover-end master mymaster 127.0.0.1 6380
    1089:X 15 Nov 2020 19:54:04.146 # +switch-master mymaster 127.0.0.1 6380 127.0.0.1 6382
    1089:X 15 Nov 2020 19:54:04.147 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6382
    1089:X 15 Nov 2020 19:54:04.147 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
    1089:X 15 Nov 2020 19:54:34.225 # +sdown slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
    

    可以看到:

    1. 19:54:02.196,Sentinel-26381认为原redis master节点6380主观下线(+sdown master mymaster 127.0.0.1 6380);
    2. 稍后,经与其他Sentinel确认,原redis master节点6380被标识为客观下线;(1089:X 15 Nov 2020 19:42:32.956 # -tilt #tilt mode exited)
    3. 准备进行故障转移;(+try-failover master mymaster 127.0.0.1 6380)
    4. Sentinel-26381被选为Sentinel leader,开始进行故障转移;
    5. 选举原master节点的从节点6382作为主节点;(+selected-slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380)
    6. 故障转移结束。

    三、使用JedisSentinelPool操作Redis

    • pom依赖

          <!-- redis 客户端 -->
          <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0</version>
          </dependency>
          <!-- 日志组件 -->
          <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.12.0</version>
          </dependency>
      
    • RedisUtils

      package com.dfx.redisdemos.util;
      
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import redis.clients.jedis.Jedis;
      import redis.clients.jedis.JedisSentinelPool;
      
      import java.util.HashSet;
      import java.util.Set;
      
      /**
       * @Author dufengxu
       * @Description
       * @Date 2020/11/21 14:34
       */
      public class RedisUtils {
      
          private static final Logger LOGGER = LoggerFactory.getLogger(RedisUtils.class);
      
          private static JedisSentinelPool sentinelPool;
          private static final String MASTER_NAME = "mymaster";
      
          static {
              Set<String> sentinelSet = new HashSet<>(3);
              sentinelSet.add("127.0.0.1:26380");
              sentinelSet.add("127.0.0.1:26381");
              sentinelSet.add("127.0.0.1:26382");
      
              // master_name 要与Sentinel监视的master名称一致
              // sentinel monitor mymaster 127.0.0.1 6380 2
              sentinelPool = new JedisSentinelPool(MASTER_NAME, sentinelSet);
          }
      
          /**
           * 增加key、val
           *
           * @param key
           * @param val
           * @return
           */
          public static boolean set(String key, String val) {
      
              Jedis jedis = null;
              try {
                  jedis = sentinelPool.getResource();
                  jedis.set(key, val);
                  return true;
              } catch (Exception e) {
                  LOGGER.info("set exception", e);
                  return false;
              } finally {
                  if (jedis != null) {
                      jedis.close();
                  }
              }
          }
      
          /**
           * 获取key对应的值
           *
           * @param key
           * @return
           */
          public static String get(String key) {
      
              Jedis jedis = null;
              try {
                  jedis = sentinelPool.getResource();
                  return jedis.get(key);
              } catch (Exception e) {
                  LOGGER.info("set exception", e);
                  return null;
              } finally {
                  if (jedis != null) {
                      jedis.close();
                  }
              }
          }
      
          /**
           * 增加key、val,并设置有效期
           *
           * @param key
           * @return
           */
          public static boolean set(String key, String val, int expireTimeInSecs) {
      
              Jedis jedis = null;
              try {
                  jedis = sentinelPool.getResource();
                  jedis.set(key, val);
                  jedis.expire(key, expireTimeInSecs);
                  return true;
              } catch (Exception e) {
                  LOGGER.info("set exception", e);
                  return false;
              } finally {
                  if (jedis != null) {
                      jedis.close();
                  }
              }
          }
      }
      

    ​ 【注】在创建JedisSentinelPool时,传入的master name入参,要与Sentinel实际监视的redis master name相一致;

    • 使用RedisUtils

      public class App {
      
          public static void main( String[] args ) {
              RedisUtils.set("k", "v");
              System.out.println(RedisUtils.get("k"));
          }
      }
      
    展开全文
  • redis集群架构

    2021-01-27 12:06:04
    这套架构使用是社区版本推出原生高可用解决方案,其架构图如下! 这里Sentinel作用有三个:监控:Sentinel会不断检查主服务器和从服务器是否正常运行。 通知:当被监控某个redis服务器出现问题,Sentinel通过...
  • Redis集群第一节 介绍1.1 redis-cluster架构图1.2 redis-cluster投票:容错1.3 架构细节:(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.(2)节点fail是通过集群中超过半数节点...
    310aecc3560ce80343924204ff849a34.png

    Redis集群

    第一节 介绍

    1.1 redis-cluster架构图
    302f354345339c88989f15018ae514c1.png
    1.2 redis-cluster投票:容错
    412954e16b9a0ac47eac1a89c79bca65.png
    1.3 架构细节:
    (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护nodeslotvalueRedis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点

    第二节 Redis集群的搭建

    Redis集群中至少应该有三个节点。要保证集群的高可用,需要每个节点有一个备份机。 Redis集群至少需要6台服务器。 搭建伪分布式。可以使用一台虚拟机运行6个redis实例。然后修改redis的端口号7001-7006(自定义端口,只要不和其他程序重复)

    2.1 集群搭建环境
    2.1.1 使用ruby脚本搭建集群。需要ruby的运行环境。
    yum install rubyyum install rubygems
    2.1.2 上传并安装ruby脚本运行使用的包。
    [root@localhost ~]# gem install redis-3.0.0.gem Successfully installed redis-3.0.01 gem installedInstalling ri documentation for redis-3.0.0...Installing RDoc documentation for redis-3.0.0...[root@localhost ~]# [root@localhost ~]# cd redis-3.0.7/src[root@localhost src]# ll *.rb-rwxrwxr-x. 1 root root 48141 Apr  1  2015 redis-trib.rb
    2.2 搭建步骤

    需要6台redis服务器。搭建伪分布式。 需要6个redis实例。 需要运行在不同的端口7001-7006

    2.2.1 创建6个redis实例,每个实例运行在不同的端口。需要修改redis.conf配置文件。配置文件中还需要把cluster-enabled yes前的注释去掉。
    2.2.2 启动每个redis实例。
    2.2.3 使用ruby脚本搭建集群。
    ./redis-trib.rb create --replicas 1 10.0.135.131:7001 10.0.135.131:7002 10.0.135.131:7003 10.0.135.131:7004 10.0.135.131:7005 10.0.135.131:7006
    2.2.4 创建关闭集群的脚本
    [root@localhost redis-cluster]# vim shutdow-all.shredis01/redis-cli -p 7001 shutdownredis01/redis-cli -p 7002 shutdownredis01/redis-cli -p 7003 shutdownredis01/redis-cli -p 7004 shutdownredis01/redis-cli -p 7005 shutdownredis01/redis-cli -p 7006 shutdown[root@localhost redis-cluster]# chmod u+x shutdow-all.sh [root@localhost redis-cluster]# ./redis-trib.rb create --replicas 1 10.0.135.131:7001 10.0.135.131:7002 10.0.135.131:7003 10.0.135.131:7004 10.0.135.131:7005  10.0.135.131:7006>>> Creating clusterConnecting to node 10.0.135.131:7001: OKConnecting to node 10.0.135.131:7002: OKConnecting to node 10.0.135.131:7003: OKConnecting to node 10.0.135.131:7004: OKConnecting to node 10.0.135.131:7005: OKConnecting to node 10.0.135.131:7006: OK>>> Performing hash slots allocation on 6 nodes...Using 3 masters:10.0.135.131:700110.0.135.131:700210.0.135.131:7003Adding replica 10.0.135.131:7004 to 10.0.135.131:7001Adding replica 10.0.135.131:7005 to 10.0.135.131:7002Adding replica 10.0.135.131:7006 to 10.0.135.131:7003M: 2e48ae301e9c32b04a7d4d92e15e98e78de8c1f3 10.0.135.131:7001   slots:0-5460 (5461 slots) masterM: 8cd93a9a943b4ef851af6a03edd699a6061ace01 10.0.135.131:7002   slots:5461-10922 (5462 slots) masterM: 2935007902d83f20b1253d7f43dae32aab9744e6 10.0.135.131:7003   slots:10923-16383 (5461 slots) masterS: 74f9d9706f848471583929fc8bbde3c8e99e211b 10.0.135.131:7004   replicates 2e48ae301e9c32b04a7d4d92e15e98e78de8c1f3S: 42cc9e25ebb19dda92591364c1df4b3a518b795b 10.0.135.131:7005   replicates 8cd93a9a943b4ef851af6a03edd699a6061ace01S: 8b1b11d509d29659c2831e7a9f6469c060dfcd39 10.0.135.131:7006   replicates 2935007902d83f20b1253d7f43dae32aab9744e6Can I set the above configuration? (type 'yes' to accept): yes>>> Nodes configuration updated>>> Assign a different config epoch to each node>>> Sending CLUSTER MEET messages to join the clusterWaiting for the cluster to join.....>>> Performing Cluster Check (using node 10.0.135.131:7001)M: 2e48ae301e9c32b04a7d4d92e15e98e78de8c1f3 10.0.135.131:7001   slots:0-5460 (5461 slots) masterM: 8cd93a9a943b4ef851af6a03edd699a6061ace01 10.0.135.131:7002   slots:5461-10922 (5462 slots) masterM: 2935007902d83f20b1253d7f43dae32aab9744e6 10.0.135.131:7003   slots:10923-16383 (5461 slots) masterM: 74f9d9706f848471583929fc8bbde3c8e99e211b 10.0.135.131:7004   slots: (0 slots) master   replicates 2e48ae301e9c32b04a7d4d92e15e98e78de8c1f3M: 42cc9e25ebb19dda92591364c1df4b3a518b795b 10.0.135.131:7005   slots: (0 slots) master   replicates 8cd93a9a943b4ef851af6a03edd699a6061ace01M: 8b1b11d509d29659c2831e7a9f6469c060dfcd39 10.0.135.131:7006   slots: (0 slots) master   replicates 2935007902d83f20b1253d7f43dae32aab9744e6[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.[root@localhost redis-cluster]# 
    2.3 集群的使用方法
    Redis-cli连接集群。[root@localhost redis-cluster]# redis01/redis-cli -p 7002 -c-c:代表连接的是redis集群

    Jedis

    1.连接单机版

    第一步:创建一个Jedis对象。需要指定服务端的ip及端口。

    第二步:使用Jedis对象操作数据库,每个redis命令对应一个方法。

    第三步:打印结果。

    第四步:关闭Jedis

    @Testpublic void testJedis() throws Exception {// 第一步:创建一个Jedis对象。需要指定服务端的ip及端口。Jedis jedis = new Jedis("10.0.135.131", 6379);// 第二步:使用Jedis对象操作数据库,每个redis命令对应一个方法。String result = jedis.get("hello");// 第三步:打印结果。System.out.println(result);// 第四步:关闭Jedisjedis.close();}

    2.连接单机版使用连接池

    第一步:创建一个JedisPool对象。需要指定服务端的ip及端口。

    第二步:从JedisPool中获得Jedis对象。

    第三步:使用Jedis操作redis服务器。

    第四步:操作完毕后关闭jedis对象,连接池回收资源。

    第五步:关闭JedisPool对象。

    @Testpublic void testJedisPool() throws Exception {// 第一步:创建一个JedisPool对象。需要指定服务端的ip及端口。JedisPool jedisPool = new JedisPool("10.0.135.131", 6379);// 第二步:从JedisPool中获得Jedis对象。Jedis jedis = jedisPool.getResource();// 第三步:使用Jedis操作redis服务器。jedis.set("jedis", "test");String result = jedis.get("jedis");System.out.println(result);// 第四步:操作完毕后关闭jedis对象,连接池回收资源。jedis.close();// 第五步:关闭JedisPool对象。jedisPool.close();}

    3.连接集群版

    第一步:使用JedisCluster对象。需要一个Set参数。Redis节点的列表。

    第二步:直接使用JedisCluster对象操作redis。在系统中单例存在。

    第三步:打印结果

    第四步:系统关闭前,关闭JedisCluster对象。

    Testpublic void testJedisCluster() throws Exception {// 第一步:使用JedisCluster对象。需要一个Set参数。Redis节点的列表。Set nodes = new HashSet<>();nodes.add(new HostAndPort("10.0.135.131", 7001));nodes.add(new HostAndPort("10.0.135.131", 7002));nodes.add(new HostAndPort("10.0.135.131", 7003));nodes.add(new HostAndPort("10.0.135.131", 7004));nodes.add(new HostAndPort("10.0.135.131", 7005));nodes.add(new HostAndPort("10.0.135.131", 7006));JedisCluster jedisCluster = new JedisCluster(nodes);// 第二步:直接使用JedisCluster对象操作redis。在系统中单例存在。jedisCluster.set("hello", "100");String result = jedisCluster.get("hello");// 第三步:打印结果System.out.println(result);// 第四步:系统关闭前,关闭JedisCluster对象。jedisCluster.close();}

    封装和整合spring

    1. 接口封装

    常用的操作redis的方法提取出一个接口,分别对应单机版和集群版创建两个实现类。

    1.接口定义

    public interface JedisClient {  String set(String key, String value);String get(String key);Boolean exists(String key);Long expire(String key, int seconds);Long ttl(String key);Long incr(String key);Long hset(String key, String field, String value);String hget(String key, String field);Long hdel(String key, String... field);}

    2.单机版实现类

    public class JedisClientPool implements JedisClient {@Autowiredprivate JedisPool jedisPool;@Overridepublic String set(String key, String value) {Jedis jedis = jedisPool.getResource();String result = jedis.set(key, value);jedis.close();return result;}@Overridepublic String get(String key) {Jedis jedis = jedisPool.getResource();String result = jedis.get(key);jedis.close();return result;}@Overridepublic Boolean exists(String key) {Jedis jedis = jedisPool.getResource();Boolean result = jedis.exists(key);jedis.close();return result;}@Overridepublic Long expire(String key, int seconds) {Jedis jedis = jedisPool.getResource();Long result = jedis.expire(key, seconds);jedis.close();return result;}@Overridepublic Long ttl(String key) {Jedis jedis = jedisPool.getResource();Long result = jedis.ttl(key);jedis.close();return result;}@Overridepublic Long incr(String key) {Jedis jedis = jedisPool.getResource();Long result = jedis.incr(key);jedis.close();return result;}@Overridepublic Long hset(String key, String field, String value) {Jedis jedis = jedisPool.getResource();Long result = jedis.hset(key, field, value);jedis.close();return result;}@Overridepublic String hget(String key, String field) {Jedis jedis = jedisPool.getResource();String result = jedis.hget(key, field);jedis.close();return result;}@Overridepublic Long hdel(String key, String... field) {Jedis jedis = jedisPool.getResource();Long result = jedis.hdel(key, field);jedis.close();return result;}}

    3.配置:applicationContext-redis.xml

    <?xml version="1.0" encoding="UTF-8"?>

    集群版实现类

    public class JedisClientCluster implements JedisClient {@Autowiredprivate JedisCluster jedisCluster;@Overridepublic String set(String key, String value) {return jedisCluster.set(key, value);}@Overridepublic String get(String key) {return jedisCluster.get(key);}@Overridepublic Boolean exists(String key) {return jedisCluster.exists(key);}@Overridepublic Long expire(String key, int seconds) {return jedisCluster.expire(key, seconds);}@Overridepublic Long ttl(String key) {return jedisCluster.ttl(key);}@Overridepublic Long incr(String key) {return jedisCluster.incr(key);}@Overridepublic Long hset(String key, String field, String value) {return jedisCluster.hset(key, field, value);}@Overridepublic String hget(String key, String field) {return jedisCluster.hget(key, field);}@Overridepublic Long hdel(String key, String... field) {return jedisCluster.hdel(key, field);}}

    Spring的配置:

    展开全文
  • Redis 主从架构

    2020-11-21 23:37:11
    Redis集群采取主从架构,采取读写分离设计方案 Master负责写 slaves负责读 Redis集群可以有多个主从,一个服务器可以同时兼任主从两种角色。即本身作为某个主从从,同时作为另一个主从主。如下Redis...
  • 【Redis】04 Redis的架构模式

    千次阅读 2019-05-08 15:16:32
    主的redis的数据有两个副本,redis1 和 redis2 主redis 和 从redis 的数据保持实时同步。主写入数据,数据会同步到从节点 一主多从。 主从复制不会阻塞主节点。同步数据的时候,主节点可以继续处理客户端的请求。 一...
  • 文章目录Redis基本架构图 Redis基本架构图 Redis基本架构为 存储模块,保存数据,数据模型为 key-value形式,value支持丰富数据类型。包括字符串,列表 ,哈希表,集合等。不同数据类型能支持不同业务需求...
  • 免责声明以下知识来源:https://juejin.im/post/5ce7efef518825332b59f79bslot架构图redis中slot和节点对应关系图:只要是redis集群版,slot个数一定是16384个!数据库中每个键都属于这16384个槽其中一个,...
  • 一、redis的主从架构 一开始我们的业务量不大时,一个redis节点就能满足我们的业务需求,当我们的业务量不断上涨,单台redis节点已经不能满足我们的业务需求时,这个时候redis的主从结构就出现了。 redis主从结构...
  • 转自: Redis主从架构和主从从架构集群搭建详细步骤 本文主要介绍Redis主从架构和主从从架构,耐心阅读完本文,相信你会对Redis主从架构和主从从架构有一个清晰认识。...1.1 Redis主从架构拓扑结构 
  • 哨兵架构下client端第一次从哨兵找出redis主节点,后续就支持访问redis的主节点,不会每次都通过sentinel代理访问reids主节点,当redis主节点发送变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端...
  • 本文主要介绍Redis主从架构和主从从架构,耐心阅读完本文,相信你会对Redis主从架构和主从从架构有一个清晰认识。 Redis主从复制功能非常强大,它有以下好处: 1.避免Redis单点故障 2.构建读写分离架构,满足读多写...
  • Redis Cluster 是 Redis 3.0 版本推出 Redis 集群方案,它将数据分布在不同服务区上,以此来降低系统对单主节点依赖,并且可以大大提高 Redis 服务读写性能。Redis 将所有数据分为 16384 个 slots(槽),...
  • Redis Cluster 是 Redis 3.0 版本推出 Redis 集群方案,它将数据分布在不同服务区上,以此来降低系统对单主节点依赖,并且可以大大提高 Redis 服务读写性能。Redis 将所有数据分为 16384 个 slots(槽),...
  • 今天我们来谈谈Redis集群这个话题,需要说明是本文 适合人群:不知道自己生产Redis集群架构,以及对Redis集群不了解人 ...这套架构使用是社区版本推出原生高可用解决方案,其架构图如下! 这里S...
  • 蓝色Redis集群中每个node节点,节点之间通过ping 命令,测试相互是否连接正常,普通集群没有主从区分,连接任何一个节点操作,都可以转发到其他任意一个节点。 1、Redis 容错机制 每个Redis提供在节点...
  • Redis Sentinel架构 概念

    2020-03-16 16:38:54
    Sentinel(哨兵)是Redis 高可用性解决方案:由一个或多个Sentinel 实例组成Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下所有从服务器,并在被监视主服务器进入下线状态时,自动将下线主...
  • 自己一步一步搭建成功,现记录下完整搭建...1.1 Redis主从架构拓扑结构 1.2 开始搭建 Redis集群不用安装多个Redis,只需复制多个配置文件,修改端口即可。所以如果要进行主从结构搭建,需先安装单机版Redis。...
  • 前言高并发十分考验架构师功底,它也是分布式架构设计中必须考虑的因素之一。...Redis常用的数据类型Redis的五种常用的数据类型分别是:String、Hash、List、Set和Sorted setRedis的使用场景1.Counting(计...
  • 最近接手一个Python web项目,项目中使用 Celery 异步执行一些耗时任务,服务每天都有部分接口阶段性出现 500 响应。查看日志发现是 Celery 在执行异步任务时与 Redis 断开连接。主要错误日志如下:File ""/usr/...
  • 缓存化针对热点商品这些类型数据,要考虑到访问量比较大,大家首先想到是缓存,上redis缓存,这点肯定没有错。系统框架如下: 上中,先从缓存中获取,没有再到DB获取,并保存到缓存中。但有个问题...
  • +redis主从架构的核心原理

    千次阅读 热门讨论 2021-03-13 15:34:21
    · 将redis缓存架构做成一主多从,主分支master node主要负责写入数据,并且将数据同步复制到其他slave node分支节点,其余从分支主要负责读取请求,所有读取数据请求全部走从节点,也就是slave node节点 ...
  • 实用的Redis集群架构

    2012-03-23 15:41:04
    用了一段时间Redis,感觉很不错,但在集群环境下,发现存在一些问题,只能自己动手解决。 1.解决在Redis cluster环境中多slave复制给...目前线上20台,运行良好,废话不多说,直接上。 ...
  • 1. redis架构图 2. redis主从工作原理 第一步:如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个SYNC命令(redis2.8版本之前命令)给master请求复制数据。 第二步:master...
  • Redis 主从复制架构Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项 让一个服务器去复制(replicate)另一个服务器 我们称呼被复制服务器为主服务器(master) 而对主服务器进行复制服务器则被称为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,836
精华内容 734
关键字:

redis的架构图

redis 订阅