zoukankan      html  css  js  c++  java
  • Redis Sentinel的Redis集群(主从&Sharding)高可用方案

    标题中的Sentinel:就连接池带哨兵模式,而不是CRUD带哨兵模式

    在不使用redis3.0之后版本的情况下,对于redis服务端一般是采用Sentinel哨兵模式,也就是一主多备的方式。

    这里,先抛出三个问题,

    问题1:单节点宕机数据丢失?
    问题2:多节点(节点间没有主从关系)数据分片,采用sharedJedisPool,某节点宕机,导致获取不到连接
    问题3:主从模式下,通过哨兵配置,单个集群数据无法分片(备复制->主的数据,备无写权限)

    关于问题1,解决方式,多台redis节点,采用Sentinel哨兵模式,也就是一主多备的方式。

    关于问题2,这里先不谈解决方式,在节点间无依赖的情况下,采用redis分片存储数据,也就是采用redis的sharedjedispool连接池,他有一个缺点,那就是当我的某个

    节点宕机后,会导致整个连接出问题。

    关于问题3,在一个集群环境下,从复制主的数据,这个时候一个集群下的redis实例之间的数据是同步,也就没有办法去做数据分片

    在不适用redis3.0后的新特征load balance,也就是 ....

    Redis Cluster  是Redis的集群实现,内置数据自动分片机制,集群内部将所有的key映射到16384个Slot中,集群中的每个Redis Instance负责其中的一部分的Slot的读写。集群客户端连接集群中任一Redis Instance即可发送命令,当Redis Instance收到自己不负责的Slot的请求时,会将负责请求Key所在Slot的Redis Instance地址返回给客户端,客户端收到后自动将原请求重新发往这个地址,对外部透明。一个Key到底属于哪个Slot由crc16(key) % 16384 决定

    关于上面三个问题,在使用redis2.X版本的情况下,解决方式就是:

    多个集群,然后就是集群之间数据分片,这样压力小很多。

    举个例子:

    看到上面的图应该就懂了。

    在这里还有一个比较坑爹的问题就是,spring封装的那套spring-data-redis ,相对于jedis真的是不太好用,而且关于哨兵的配置文件,就是下面这段,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <bean id="sentinelConfiguration" 
        class="org.springframework.data.redis.connection.RedisSentinelConfiguration"
        <property name="master"
            <bean class="org.springframework.data.redis.connection.RedisNode"
                <property name="name" value="mymaster"></property> 
            </bean> 
        </property> 
        <property name="sentinels"
            <set> 
                <bean class="org.springframework.data.redis.connection.RedisNode"
                    <constructor-arg name="host" 
                        value="192.168.8.50"></constructor-arg> 
                    <constructor-arg name="port" 
                        value="26379"></constructor-arg> 
                </bean> 
            </set> 
        </property> 
    </bean> 

      我在spring3.x版本下,死活报错,注入不了sentinels,然而打开源码去看,确实是有的,换成spring4.X后,就没有出现问题。

    叹气!!!

    决定弃用spring-data-redis,还是采用jedis。

    但是jedis也有一个问题,在jedis2.5之后增加了redis.clients.jedis.JedisSentinelPool这个哨兵管理连接池,他也有一个问题,就是他取得的redis操作实例是jedis,而不是sharedJedis,因为sharedJedis,是从sharedJedisPool里面取出的,这样是不是又有一个问题,嗯,支持集群了,但不支持分片了!!

    显然不是我们想要的,怎么办呢,Google了下,在github上找到有人去写了一个连接池,地址在这

    https://github.com/warmbreeze/sharded-jedis-sentinel-pool,

    代码拿下来后,看了下,应该是可以的,加上测试下。

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans
     xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:p="http://www.springframework.org/schema/p"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        <!-- 连接池配置 -->
         <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxIdle" value="8" />
            <property name="maxTotal" value="50" />  
            <property name="maxWaitMillis" value="1000" /> 
            <property name="testOnBorrow" value="true" />
            <property name="testOnReturn" value="true" />
         </bean>
        <!-- jedis连接池配置 -->
    <!--     <bean id="jedisPool" class="redis.clients.jedis.JedisSentinelPool">
            <constructor-arg index="0" value="mymaster" />
            <constructor-arg index="1">
                <set>
                    <value>192.168.8.50:26379</value>
                </set>
            </constructor-arg>
            <constructor-arg index="2" ref="jedisPoolConfig" />
        </bean> -->
        <!-- 自定义分片处理哨兵池配置 -->
        <bean id="shardedJedisPool" class="com.yto.demo.java.jedis.spring.sentinel.pool.ShardedJedisSentinelPool">
            <constructor-arg index="0" ref="jedisPoolConfig" />
            <constructor-arg index="1">
                <list>
                    <value>mymaster</value> <!-- 集群1 -->
                    <value>mymaster02</value> <!-- 集群2 -->
                    
                </list>
            </constructor-arg>
            <constructor-arg index="2">
                <set>
                    <value>192.168.8.50:26379</value>
                    <value>192.168.8.50:26479</value>
                </set>
            </constructor-arg>
        </bean>
        <!-- 自定义抽象jedis 信息 -->
        <bean id="redisDataSource"  class="com.yto.demo.java.jedis.spring.api.impl.RedisSharedSentinelDataSourceImpl">
            <property name="shardedJedisPool" ref="shardedJedisPool"></property>
        </bean>
        
        <bean id="redisClientTemplate"  class="com.yto.demo.java.jedis.spring.client.RedisSharedSentinelClientTemplate">
            <property name="redisDataSource" ref="redisDataSource"></property>
        </bean>
        
        
     </beans>  
    复制代码
    ShardedJedisSentinelPool这个代码自己去git上面拿下来吧!!至于里面有没有bug我还没仔细去看里面的代码,但是确实支持主从+分片了。。

    本文转自:https://www.cnblogs.com/xiaoblog/p/5776892.html
  • 相关阅读:
    hdu_6836 Expectation
    hdu_6820 Tree
    luogu P1039 侦探推理
    自己动手实现区块链
    第六章 钱包管理界面和区块链浏览器
    第五章 自己动手写比特币之交易中继
    第四章 自己动手写比特币之钱包
    第三章 自己动手写区块链之交易
    第二章 工作量证明和挖矿
    第一章:最小可行区块链
  • 原文地址:https://www.cnblogs.com/nizuimeiabc1/p/8568505.html
Copyright © 2011-2022 走看看