1. 程式人生 > >springboot配置Redis主從服務

springboot配置Redis主從服務

今天學了一下springboot配置redis的主從伺服器。根據一主二從三哨兵的原則來搭建一個分散式的快取服務。主要還是針對redis的一些配置。下面與大家分享一下!
附上對redis的官方介紹
http://redis.majunwei.com/topics/sentinel.html
要想通過springboot搭建redis主從服務,就要先使用redis配置一個主從服務。

測試redis的主從配置

  • 主伺服器用於資料的讀寫,當發生寫入操作時,主伺服器會自動將資料同步給從伺服器。
  • 從伺服器只負責讀取,不能寫入。如果主伺服器宕機,哨兵(sentinel)會在從伺服器中選舉產生一個主伺服器。此時該伺服器具有讀寫許可權。
    下面我們分步驟來配置主從伺服器,依照一主二從三哨兵的原則,我們需要三個redis例項,分別配置如下資訊

redis例項

資料夾名稱如下

redis_master_s
redis_slaver1_s
redis_slaver2_s

redis.conf檔案

master的redis.conf檔案(其餘是預設設定)

port 6379
daemonize yes
# 這個資料夾要改成自己的目錄
dir "/Users/vobile_lzl/redis_master_s"

slaver1的redis.conf檔案

port 6378
# 主伺服器埠為6379
slaveof 127.0.0.1 6379
dir "/Users/vobile_lzl/redis_slaver1_s"

slaver2的redis.conf檔案

port 6377
# 主伺服器埠為6379
slaveof 127.0.0.1 6379
dir "/Users/vobile_lzl/redis_slaver2_s"

這個主從伺服器就配置好了。
啟動服務(命令大致如此)

./redis-server redis.conf

測試一下主從複製的功能
1. 主伺服器寫入,從伺服器可以讀取到
2. 從伺服器不能寫入

注意埠,6379表示主伺服器,6377、6378是從伺服器

127.0.0.1:6379> set name lzl
OK
127.0.0.1:6377> get name
"lzl" 127.0.0.1:6378> get name "lzl" # 從伺服器不能寫入 127.0.0.1:6378> set name lzl (error) READONLY You can't write against a read only slave. 127.0.0.1:6377> set nam fdk (error) READONLY You can't write against a read only slave.

sentinel.conf檔案

sentinel是哨兵,用於監視主從伺服器的執行狀況,如果主伺服器掛掉,會在從伺服器中選舉一個作為主伺服器。
配置檔案如下
master的sentinel.conf

port 26379
# 初次配置時的狀態,這個sentinel會自動更新
sentinel monitor mymaster 127.0.0.1 6379 2
daemonize yes
logfile "./sentinel_log.log"

slaver1的sentinel.conf

port 26378
# 初次配置時的狀態,這個sentinel會自動更新
sentinel monitor mymaster 127.0.0.1 6379 2
daemonize yes
logfile "./sentinel_log.log"

slaver2的sentinel.conf

port 26377
# 初次配置時的狀態,這個sentinel會自動更新
sentinel monitor mymaster 127.0.0.1 6379 2
daemonize yes
logfile "./sentinel_log.log"

再次啟動redis所有的服務端

./redis-server redis.conf
./redis-server sentinel.conf --sentinel

分別開啟redis的客戶端

./redis-cli
./redis-cli -h 127.0.0.1 -p 6378
./redis-cli -h 127.0.0.1 -p 6377

使用一下命令檢視三個redis服務的狀態

info replication

master
role:master

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6378,state=online,offset=4102,lag=1
slave1:ip=127.0.0.1,port=6377,state=online,offset=4102,lag=1
master_repl_offset:4102
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:4101

slaver1

127.0.0.1:6378> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:15931
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

slaver2

127.0.0.1:6377> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:21629
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

將master服務殺死

vobile-lzldeMacBook-Pro:~ vobile_lzl$ ps -ef | grep redis
  501 13258     1   0  9:52下午 ??         0:00.37 ./redis-server *:6379 

  kill -9 13258

再次檢視master的狀態
說明master已經宕機

127.0.0.1:6379> info replication
Could not connect to Redis at 127.0.0.1:6379: Connection refused

再觀察一段時間,6377的從伺服器成為主伺服器

127.0.0.1:6377> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

恢復主伺服器,並設定為master

// TODO

springboot中配置主從redis

application.properties檔案

新增node配置

// 主從配置
// name of Redis server  哨兵監聽的Redis server的名稱
spring.redis.sentinel.master=mymaster
// comma-separated list of host:port pairs  哨兵的配置列表
spring.redis.sentinel.nodes=127.0.0.1:26379,127.0.0.1:26378,127.0.0.1:26377

RedisCacheConfig配置

新增RedisSentinelConfiguration程式碼

 /**
     * redis哨兵配置
     * @return
     */
    @Bean
    public RedisSentinelConfiguration redisSentinelConfiguration(){
        RedisSentinelConfiguration configuration = new RedisSentinelConfiguration();
        String[] host = redisNodes.split(",");
        for(String redisHost : host){
            String[] item = redisHost.split(":");
            String ip = item[0];
            String port = item[1];
            configuration.addSentinel(new RedisNode(ip, Integer.parseInt(port)));
        }
        configuration.setMaster(master);
        return configuration;
    }

/**
     * 連線redis的工廠類
     *
     * @return
     */
    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
    //構造方法中注入RedisSentinelConfiguration物件
        JedisConnectionFactory factory = new JedisConnectionFactory(redisSentinelConfiguration());
        factory.setHostName(host);
        factory.setPort(port);
        factory.setTimeout(timeout);
        factory.setPassword(password);
        factory.setDatabase(database);
        return factory;
    }

以上就是redis的主從配置。十分簡單!
接下來就要驗證一把在springboot中是否配置成功!
驗證思路
* 寫一個controller方法,用來往redis中新增資料
* 此時關閉redis主伺服器,再次呼叫contoller方法、
* 如果介面依舊可以寫入資訊,說明配置成功。此時檢視redis的其他從伺服器,會發現有一個從伺服器變成了主伺服器。
測試程式碼:

@RestController
@RequestMapping("sample")
public class SampleController {

    @Autowired
    private UseRedisDao useRedisDao;

    @RequestMapping("hi")
    public String sayHello(String key,String value){
        useRedisDao.setValue(key,value);
        return useRedisDao.getValue(key);
    }
}

先檢視redis主伺服器發現,6377是master伺服器

127.0.0.1:6377> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6378,state=online,offset=378547,lag=1
slave1:ip=127.0.0.1,port=6379,state=online,offset=378547,lag=1
master_repl_offset:378682
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:378681
127.0.0.1:6379> keys *
1) "code"
2) "name"
127.0.0.1:6379> get code 
"\"good\""

我們看到三個redis服務都存在這樣的資訊
這裡寫圖片描述
這時kill掉6377的程序

vobile-lzldeMacBook-Pro:redis_slaver2_s vobile_lzl$ ./redis-cli -p 6377 shutdown
vobile-lzldeMacBook-Pro:redis_slaver2_s vobile_lzl$ ./redis-cli -p 6377
Could not connect to Redis at 127.0.0.1:6377: Connection refused
127.0.0.1:6378> keys *
1) "code"
2) "name"
3) "today"

127.0.0.1:6379> keys *
1) "code"
2) "name"
3) "today"

此時看到6379變成了master

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6378,state=online,offset=32419,lag=1
master_repl_offset:32419
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:32418