探索雲原生技術之基石——Docker容器

文章目錄

什麼是雲原生

什麼是 Docker

MySQL 主從複製(1 主 1 從)

Redis 集羣(3 主 6 從)

什麼是雲原生

Pivotal 公司的 Matt Stine 於 2013 年首次提出雲原生(Cloud-Native)的概念;2015 年,雲原生剛推廣時,Matt Stine 在《遷移到雲原生架構》一書中定義了符合雲原生架構的幾個特徵:12 因素、微服務、自敏捷架構、基於 API 協作、扛脆弱性;到了 2017 年,Matt Stine 在接受 InfoQ 採訪時又改了口風,將雲原生架構歸納爲模塊化、可觀察、可部署、可測試、可替換、可處理 6 特質;而 Pivotal 最新官網對雲原生概括爲 4 個要點:DevOps + 持續交付 + 微服務 + 容器。

總而言之,符合雲原生架構的應用程序應該是:採用開源堆棧(K8S+Docker)進行容器化,基於微服務架構提高靈活性和可維護性,藉助敏捷方法、DevOps 支持持續迭代和運維自動化,利用雲平臺設施實現彈性伸縮、動態調度、優化資源利用率。

什麼是 Docker

總而言之:

Docker 是一個高性能的容器引擎;

可以把本地源代碼、配置文件、依賴、環境通通打包成一個容器即可以到處運行;

使用 Docker 安裝軟件十分方便,而且安裝的軟件十分精簡,方便擴展。

MySQL 主從複製(1 主 1 從)

Master 節點配置

在主數據庫創建的該帳號密碼只是用來進行同步數據。

Slave 節點配置

[root@aubin ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
2c4136668536   mysql:5.7   "docker-entrypoint.s…"   3 minutes ago   Up 9 seconds   33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp   mysql-slave
20fc7174d1a7   mysql:5.7   "docker-entrypoint.s…"   15 hours ago    Up 8 minutes   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-master

在 Master 節點中找到 ens33 的 ip 地址並放到下面的 master_host 中(記住這個 ip 是 Master 數據庫的服務器 ip,不是從數據庫的):

記住下面這個命令要在從(slave)數據庫執行:

change master to master_host='192.168.184.132',master_user='slave',
master_password='123456',master_port=3307,master_log_file='order-
mysql-bin.000001',master_log_pos=617,master_connect_retry=30;

配置參數解析

  1. master_host:主數據庫(Master)的 ip 地址

  2. master_user:在 Master 數據庫中創建的用來進行同步的帳號

  3. master_password:在 Master 數據庫中創建的用來進行同步的帳號的密碼

  4. master_port:Master 數據庫的 MySQL 端口號,這裏是 3307

  5. master_log_file:MySQL 的 binlog 文件名

  6. master_log_pos:binlog 讀取位置

我們找到裏面的 Slave_IO_Running: No,Slave_SQL_Running: No 屬性,發現都是 No 的狀態,證明主從同步還沒有開始。。。

我們可以看到已經都爲 yes 了,說明主從同步已經開啓。

測試主從同步

在 Master 數據庫執行:

也可以用 Navicat 去連接這兩個數據庫。如果 Navicat 出現連接不了 docker 的 mysql,則可以:

方法一:關閉防火牆(測試環境用,生產環境不可以用)

方法二:開放防火牆對應端口,比如 master 數據庫的 3307 和 slave 數據庫的 3308(生產環境用這個)

主從同步失敗問題(Slave_SQL_Running:No)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.184.132
                  Master_User: slave
                  Master_Port: 3307
                Connect_Retry: 30
              Master_Log_File: order-mysql-bin.000001
          Read_Master_Log_Pos: 3752
               Relay_Log_File: 2c4136668536-relay-bin.000002
                Relay_Log_Pos: 326
        Relay_Master_Log_File: order-mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 1007
                   Last_Error: Error 'Can't create database 'mall';
                    database exists' on query. Default database: 
                    'mall'. Query: 'create database mall'

Slave_SQL_Running:No 的解決辦法

1:把主數據庫和從數據庫變成一模一樣,也就是把多餘的數據庫和表刪除掉,變成默認的 mysql 狀態。(切記生產環境下要做好數據備份!!!)

2:結束同步:

3:再次開啓同步:

4:搞定!

Redis 集羣(3 主 6 從)

10 億條數據怎麼進行緩存

哈希取餘算法(小廠採用)

過程

1:假設一共有 5 臺 Redis 服務器,編號分別爲:0 1 2 3 4,服務器臺數爲 count=5

2:先把 key(關鍵字)進行哈希後產生一個哈希值爲 val,假設這個 val 爲 22

3:再用哈希取餘算法公式:val%count,也就是 22%5=2

4:那麼就定位到 3 號(0 爲 1 號機器),那麼該數據就插入 3 號 Redis 機器中

缺點:

1:Redis 節點擴容十分麻煩,如果此時從 5 臺機器變成 10 臺,那麼我們需要去修改哈希取餘算法的公式,不利於擴展。

2:又或者是縮容也十分麻煩,如果有一臺服務器宕機了,在線機器從 5->4 臺,那麼也需要去修改哈希取餘算法公式。

一致性 hash 算法(中大廠採用)

圖解:

先虛擬一個哈希環, 記錄我們機器的 ip 的 hash 對應到哈希環中:

將對象的關鍵字 key 進行 hash,順時針尋找我們的機器,如果機器還在線就插入:

過程

1:虛擬一個哈希環(類似於大小爲 2^32 的數組 arr),即 0 ~ (2^32)-1 的空間中。

2:對我們所有的 Redis 節點所在的服務器 IP 或者主機名進行 hash,得到的這個 hash 值記錄下來。

3:先把 key(關鍵字)進行 hash 後產生一個 hash 值爲 val

4:把這個 val 當成數組的下標進行遍歷(也就是從這個位置順時針遍歷哈希環)一旦遇到 Redis 節點的 hash 值則進行插入,如果該節點宕機了則插入失敗,這個時候我們就會跳過這個 Redis 節點繼續順時針搜索合適的節點,直到插入成功或者遍歷完整個哈希環(當然此時是最壞情況)。

5:如果有新增的節點就按照第 2 步操作即可

6:如果 Redis 節點被刪除或者宕機了,就移除這個記錄的節點即可。

優點:

方便擴容和縮容,不需要和哈希取餘算法一樣更改算法公式,擴展性很好。

是因爲哈希環的大小是 2^32,幾乎涵蓋了所有 hash 值的可能。

缺點:

hash 槽算法(大廠採用、和 Redis 集羣也是採用這種)

1:由於一致性 hash 算法會導致數據傾斜問題,而 hash 槽可以避免這個問題。

2:Redis 的 hash 槽大小固定爲:16384 個。

3:將 hash 槽均勻分配到各個 Master 節點上(注意:slave 節點不會被分配)

4:假如有三個 Redis 節點,則會分配成 5461:5462:5461

5:將關鍵字(key)進行 hash 取值,並且映射到對應的 hash 槽位上。

6:如果需要擴容或者縮容,只需要重新分配槽位即可。

快速搭建 Redis Cluster(3 主 6 從)

搭建的集羣爲:3 主 6 從。

其中內部是 1 個 Master 主節點對應 2 個 slave 從節點

快速生成 9 個容器實例

查看容器實例是否全部啓動

配置主從

以集羣的方式進入 Redis 客戶端

操作 set 命令

查看集羣節點信息

查看集羣狀態

主從切換

192.168.184.132:6383> CLUSTER NODES
c9d7f4ed642fa2fde013f2b060476b542b9af76e 192.168.184.132:6385
@16385 slave af28288480e3398b18402e4475c9ae52c39ea776 0 
1651767445299 3 connected
9ef7a5bb156de64a969688eade8535399983dd00 192.168.184.132:6389
@16389 slave 29a79c9f9a007bf80fdfc2ffaaf1cf27d29396c2 0 
1651767443000 10 connected
888158ad30d9a173175b115974b9d1cc5b39736e 192.168.184.132:6381
@16381 master,fail - 1651767320800 1651767314000 1 disconnected
1ff5a2a15526e3d7984b231cf7e47f8f442e4a9e 192.168.184.132:6382
@16382 master - 0 1651767444000 2 connected 5461-10922
29a79c9f9a007bf80fdfc2ffaaf1cf27d29396c2 192.168.184.132:6386
@16386 master - 0 1651767444000 10 connected 0-5460
92d06bfb428a1358149c209c336152cae3304c66 192.168.184.132:6388
@16388 slave af28288480e3398b18402e4475c9ae52c39ea776 0 
1651767443000 3 connected
af28288480e3398b18402e4475c9ae52c39ea776 192.168.184.132:6383
@16383 myself,master - 0 1651767443000 3 connected 10923-16383
5b20d04646f7f38eb57266b81749e565825ab6e5 192.168.184.132:6387
@16387 slave 1ff5a2a15526e3d7984b231cf7e47f8f442e4a9e 0 
1651767444284 2 connected
a11993ddc7a726e3ad476858fb53bdc97d4834b8 192.168.184.132:6384
@16384 slave 1ff5a2a15526e3d7984b231cf7e47f8f442e4a9e 0 
1651767446319 2 connected

我們可以看到以前 6381 的從節點 6386 變成了 Master 節點。說明已經進行主從切換了。

docker start redis-node-1
192.168.184.132:6383> CLUSTER NODES
c9d7f4ed642fa2fde013f2b060476b542b9af76e 192.168.184.132:6385
@16385 slave af28288480e3398b18402e4475c9ae52c39ea776 0 
1651767586000 3 connected
9ef7a5bb156de64a969688eade8535399983dd00 192.168.184.132:6389
@16389 slave 29a79c9f9a007bf80fdfc2ffaaf1cf27d29396c2 0 
1651767586183 10 connected
888158ad30d9a173175b115974b9d1cc5b39736e 192.168.184.132:6381
@16381 slave 29a79c9f9a007bf80fdfc2ffaaf1cf27d29396c2 0 
1651767582247 10 connected
1ff5a2a15526e3d7984b231cf7e47f8f442e4a9e 192.168.184.132:6382
@16382 master - 0 1651767586000 2 connected 5461-10922
29a79c9f9a007bf80fdfc2ffaaf1cf27d29396c2 192.168.184.132:6386
@16386 master - 0 1651767588204 10 connected 0-5460
92d06bfb428a1358149c209c336152cae3304c66 192.168.184.132:6388
@16388 slave af28288480e3398b18402e4475c9ae52c39ea776 0 
1651767586000 3 connected
af28288480e3398b18402e4475c9ae52c39ea776 192.168.184.132:6383
@16383 myself,master - 0 1651767587000 3 connected 10923-16383
5b20d04646f7f38eb57266b81749e565825ab6e5 192.168.184.132:6387
@16387 slave 1ff5a2a15526e3d7984b231cf7e47f8f442e4a9e 0 
1651767585000 2 connected
a11993ddc7a726e3ad476858fb53bdc97d4834b8 192.168.184.132:6384
@16384 slave 1ff5a2a15526e3d7984b231cf7e47f8f442e4a9e 0 
1651767587192 2 connected

我們可以看到 6381 變成了從節點(slave),主節點(Master)是 6386。

主從擴容

發現 6390 已經成功加入到集羣,並且是 Master 節點,但是沒有被分配槽位,slots 爲 0。需要分配槽位纔有用

主從縮容

此時 6390 的槽位已經全部給了 6383,這個時候可以刪除 6390 節點了。xxx1 爲 6390 的容器 id

來源:

https://blog.csdn.net/weixin_50071998/article/details/124751540

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/TKxDtU-z8qtf_oI0GX0eSQ