Redis 入門到高可用以及分佈式實戰(二)

上一篇文章 Redis從入門到高可用以及分佈式實戰(一)介紹了Redis的基本命令、五大數據結構、Redis的到典型應用場景,經過以前的學習咱們對Redis有了一點的瞭解,接下來這篇文章會講解Redis的主從複製原理的配置、哨兵選舉原理並掌握在Linux上搭建Redis一主二從三哨兵高可用集羣環境,廢話少說,讓咱們開始吧!java

阿里雲服務器搭建redis高可用集羣環境(一主二從三哨兵)

環境與工具mysql

  • 阿里雲輕量級服務器1核2GB(傳說中的乞丐版服務器)
  • Redis-5.0.4

部署工具程序員

  • Xshell 6
  • Xftp 6

開發工具web

  •  Intellij IDEA 2019.2(最新版本真香)

安裝redis

我的的redis版爲redis-5.0.4,這個看你的選擇吧,不須要選最新的,安裝路徑/opt/redis-5.0.4,建議軟件的暗轉路徑選擇/opt下,好比tomcat,mysql等...redis

Linux下安裝redis步驟:spring

下載地址:http://download.redis.io/releases/redis-5.0.5.tar.gz  直接使用wget命令下在到安裝的目錄下sql

  • 解壓:tar -zxvf redis-5.0.4.tar.gz 
  • 進入到解壓後的文件夾裏邊 :cd redis-5.0.4/
  • 編譯而且測試編譯的結果 :make
  • 進入src目錄:make install
  • 安裝完成

配置文件

第一步:redis的主從配置shell

1.使用vim命令建立redis-6379.conf配置文件(mater主配置文件),修改配置內容:數據庫

#演示方便,開放全部的ip鏈接
bind 0.0.0.0
#後臺運行
daemonize yes
#pid文件
pidfile /var/run/redis_6379.pid
dbfilename dump-6379.rdb
#日誌文件
logfile "6379.log"

2.使用命令 cp -v redis-6379.conf redis-6380.conf 複製一份redis-6379.conf 到 redis-6380.conf,修改配置文件:vim

bind 0.0.0.0
port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
dbfilename dump-6380.rdb
logfile "6380.log"
#slaveof表示做爲從庫的配置
slaveof 39.106.115.134 6379
#從庫只能讀操做
slave-read-only yes

3.一樣操做,複製一份成redis-6381.conf,修改配置文件:

bind 0.0.0.0
port 6381
daemonize yes
pidfile /var/run/redis_6381.pid
dbfilename dump-6381.rdb
logfile "6381.log"
#slaveof表示做爲從庫的配置
slaveof 39.106.115.134 6379
#從庫只能讀操做
slave-read-only yes

配置成功後,查看redis信息:

1.查看主庫信息:

[root@localhost redis-5.0.4]# ./src/redis-cli -p 6379 info

2.查看從庫信息:

3. 想知道redis主從模式是否搭建成功,咱們來實驗一下,在主庫set,從從庫裏get,看看能不能實現數據同步,看下面:

 

咱們發現是成功的,這裏注意的是,從庫只能讀數據,不能寫數據,由於咱們在配置文件裏配置了(不信你能夠試試,會報錯,報錯以下):

  • slave-read-only yes  #從庫只能讀操做

第二步:哨兵配置

建立sentinel配置文件

1.在redis.conf同一級目錄下建立sentinel-26379.conf文件,修改配置配置文件爲:

port 26379
daemonize yes
# sentinel announce-ip <ip>
# sentinel announce-port <port>
dir /opt/redis-5.0.4/data
logfile "26379.log"
sentinel monitor mymaster 39.106.115.134 6379 2
# sentinel auth-pass <master-name> <password>
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
# sentinel notification-script <master-name> <script-path>

2. 使用 cp 命令拷貝一份成 sentinel-26380.conf 和一份 sentinel-26381.conf 並修改上面port端口號等幾處地方便可,比較機械,我就不演示操做了,建立好哨兵配置文件以後,咱們就要開始啓動redis服務了,啓動成功以後使用 ps -ef | grep redis 查看redis進程信息,以下所示,代表啓動完成:

如今主庫、從庫、哨兵都啓動成功了,咱們能夠查看一下配置信息是否正確:

執行 ./src/redis-cli -p 26379.conf info

###   發現咱們的配置已經成功!!

編寫測試代碼

在IDEA建立一個maven項目,在pom文件添加redis客戶端Jedis依賴:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0-m1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

在Application中建立main函數入口,鍵入測試代碼:

/**
 * @Author 林必昭
 * @Date 2019/10/22 20:17
 */
@SpringBootApplication
public class JedisDemoApplication {

    public static void main(String[] args) {

        //三個哨兵
        Set<String> sentinels = new HashSet<>();
        //是阿里雲外網ip
        sentinels.add("39.106.115.134:26379");
        sentinels.add("39.106.115.134:26380");
        sentinels.add("39.106.115.134:26381");

        //初始化哨兵池
        JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);

        while (true) {
            Jedis jedis = null;
            try {
                //拿到jedis,經過jedis來操做主庫
                jedis = pool.getResource();
                //獲取主庫的ip
                String ip = jedis.getClient().getHost();
                //獲取主庫的端口
                int port = jedis.getClient().getPort();

                String key = "k-" + new Random().nextInt(10000);
                String value = "v-" + new Random().nextInt(10000);
                jedis.set(key, value);
                System.out.println("當前主庫:" + ip + ":" + port + "," + key + "value is " + jedis.get(key));
                //每秒執行一次
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (jedis != null) {
                    jedis.close();
                }
            }
        }
    }
}

運行mian函數,能夠看到相似的輸出:

咱們去查看數據庫數據,發現數據已經寫入了:

查看咱們的客戶端,確實數據已經寫入:

Redis高可用測試

注意:測試過程當中要保證測試代碼要一致處於運行狀態,不要斷開,如今測試代碼是後臺運行不斷向主庫插入數據,測試高可用:

1.使用 ps -ef | grep redis 查看後臺的進程,看看主庫的pid進程號:

2. 接下來,咱們要模擬主庫宕機的情景了,就是銷燬主庫進程:

    執行命令:kill 8711

看看IDEA控制檯的輸出:

 

當 kill 掉主庫進程的時候,IDEA就會報錯:Connection refused:connect 的錯誤,持續報錯,通過30s以後(這個時間是能夠選擇的,在配置文件中設置),也就是以前配置的sentinel,有一段配置 sentinel down-after-milliseconds mymaster 30000,設置主庫宕機以後通過多久時間進行選舉,單位是毫秒,這裏設置了30000毫秒,此時主庫被切換了,此時從庫redis-6381,被選舉成新的主庫,看到控制檯輸出,當前主庫變爲了:39.106.115.134:6381,6379已經被咱們停掉了,這就是redis主庫master宕機以後的從新選舉過程!!!

3. 咱們能夠可查看6381的信息,執行命令:

    ./src/redis -cli -p 6781 info 

咱們能夠清楚的看到,6381 role已是master了,也就是是6381已是主節點了,6379已經被咱們他停掉了,因此看不到6379的信息。

4.執行 ./src/redis-cli -p 26379 info;

5. 那麼,到這裏咱們就會想,6379被雖然咱們 kill 掉了,到時它會變爲從節點嗎?咱們能夠查看一下配置信息,看一下 sentinel-26379.conf 配置文件信息:

從配置文件上能夠看出,雖然6379被停掉,主庫選舉成功,這裏的6379最後仍是會被修改爲從節點,啊哈哈哈,到這裏,證實了咱們redis的高可用測試成功了!!!

問題解決

其實在搭建的過程當中遇到了不少問題,有一個問題想跟你們分享,避免入坑,一搜網上不少中說法,先把問題貼出來:

實時這個問題的來源主要緣由有兩種:

  1. ip地址的選擇問題,我選用的是阿里雲外網ip(內網彷佛不行)
  2. 配置文件的問題

對於配置文件問題的解決的方案是,修改配置文件:

  • 刪除默認的redis.conf和sentinel.conf,避免咱們寫的conf配置文件與默認文件衝突,將默認的刪除就好了;
  • 修改全部sentinel配置文件的ip,先停掉全部的節點和哨兵,將配置文件的中的ip地址信息修改成本身服務器的ip,將#Generated by下面的內容刪掉便可;

而後再從新啓動,這樣異常就能解決掉了,個人是第二種狀況引發的錯誤,百度了好久,我還從新配置了幾遍,哎555,緣由是以前配置的信息錯誤,刪掉以後從新啓動就好了,最後,Redis從入門到高可用以及分佈式實戰(二)就到這裏了,經過這篇文章咱們學習了redis一主二從三哨兵的集羣模式,Redis Sentinal着眼於高可用,在master宕機時會自動將slave提高爲master,繼續提供服務,下一篇文章咱們能夠談談 redis故障轉義的原理和過程,逐步掌握非關係型數據庫的原理和應用。

不早了,晚安了,祝你們1024節日快樂,最後,我是程序員,我爲本身帶鹽(哈哈哈)!!

相關文章
相關標籤/搜索