Docker 搭建 Redis Cluster 集羣環境

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 Docker 搭建 Redis Cluster,最重要的環節就是容器通信的問題,這一塊我們在之前的文章中已經給大家解決了《"},{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/97355a6e7ac01bce8532d5ff5","title":""},"content":[{"type":"text","text":"Docker網絡模式詳解及容器間網絡通信"}]},{"type":"text","text":"》,本篇文章主要練習使用多個容器完成 Redis Cluster 集羣環境的搭建,順便爲學習 Docker Compose 鋪鋪路。俗話說沒有對比就沒有傷害,通過對比才能感受到 Docker Compose 的好處 😄。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  關於 Redis Cluster 集羣更多的內容請閱讀《"},{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/fe070dcadf891d3d641132c36","title":""},"content":[{"type":"text","text":"最通俗易懂的 Redis 架構模式詳解"}]},{"type":"text","text":"》。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"環境"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  本文所使用的基礎設施環境如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"CentOS 7.8.2003"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Docker version 19.03.12 "}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/03/0309ecfc01393c56c1e87247cc673c77.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"搭建"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  整體搭建步驟主要分爲以下幾步:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建網絡;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下載 Redis 鏡像(其實這步可以省略,因爲創建容器時,如果本地鏡像不存在,就會去遠程拉取);"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"編寫 Redis 配置文件;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建 Redis 容器;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建 Redis Cluster 集羣。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"創建網絡"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  爲什麼需要創建網絡?因爲:默認的 bridge 網絡是無法使用 DNS 的,所以我們就需要自定義網絡。說簡單點就是爲了讓容器可以直接通過容器名稱進行通信。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  從 Docker 1.10 版本開始,docker daemon 實現了一個內嵌的 DNS server,使容器可以直接通過容器名稱進行通信。方法很簡單,只要在創建容器時使用 "},{"type":"codeinline","content":[{"type":"text","text":"--name"}]},{"type":"text","text":" 爲容器命名即可。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  但是使用 Docker DNS 有個限制:"},{"type":"text","marks":[{"type":"strong"}],"text":"只能在 user-defined 網絡中使用"},{"type":"text","text":"。也就是說,默認的 bridge 網絡是無法使用 DNS 的,所以我們就需要自定義網絡。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  通過 "},{"type":"codeinline","content":[{"type":"text","text":"docker network create"}]},{"type":"text","text":" 命令可以創建自定義網絡模式,默認爲 "},{"type":"codeinline","content":[{"type":"text","text":"bridge"}]},{"type":"text","text":" 網橋/橋接模式,完整命令如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"docker network create redis-net"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  通過 "},{"type":"codeinline","content":[{"type":"text","text":"docker network ls"}]},{"type":"text","text":" 查看網絡模式:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/00/0086d870d9540478cf1421714e28e943.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  我們還可以通過 "},{"type":"codeinline","content":[{"type":"text","text":"docker network inspect redis-net"}]},{"type":"text","text":" 查看 "},{"type":"codeinline","content":[{"type":"text","text":"redis-net"}]},{"type":"text","text":" 網絡的詳細信息:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/86/864cc532a8fa020da84fc38297a4c623.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"編寫 Redis 配置文件"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"創建目錄及文件"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# 創建目錄\nmkdir -p /usr/local/docker-redis/redis-cluster\n# 切換至指定目錄\ncd /usr/local/docker-redis/redis-cluster/\n# 編寫 redis-cluster.tmpl 文件\nvi redis-cluster.tmpl"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"編寫配置文件"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "},{"type":"codeinline","content":[{"type":"text","text":"redis-cluster.tmpl"}]},{"type":"text","text":" 文件內容如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"tepl"},"content":[{"type":"text","text":"port ${PORT}\nrequirepass 1234\nmasterauth 1234\nprotected-mode no\ndaemonize no\nappendonly yes\ncluster-enabled yes\ncluster-config-file nodes.conf\ncluster-node-timeout 15000\ncluster-announce-ip 192.168.10.10\ncluster-announce-port ${PORT}\ncluster-announce-bus-port 1${PORT}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"port"}]},{"type":"text","text":":節點端口;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"requirepass"}]},{"type":"text","text":":添加訪問認證;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"masterauth"}]},{"type":"text","text":":如果主節點開啓了訪問認證,從節點訪問主節點需要認證;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"protected-mode"}]},{"type":"text","text":":保護模式,默認值 yes,即開啓。開啓保護模式以後,需配置 "},{"type":"codeinline","content":[{"type":"text","text":"bind ip"}]},{"type":"text","text":" 或者設置訪問密碼;關閉保護模式,外部網絡可以直接訪問;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"daemonize"}]},{"type":"text","text":":是否以守護線程的方式啓動(後臺啓動),默認 no;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"appendonly"}]},{"type":"text","text":":是否開啓 AOF 持久化模式,默認 no;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"cluster-enabled"}]},{"type":"text","text":":是否開啓集羣模式,默認 no;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"cluster-config-file"}]},{"type":"text","text":":集羣節點信息文件;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"cluster-node-timeout"}]},{"type":"text","text":":集羣節點連接超時時間;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"cluster-announce-ip"}]},{"type":"text","text":":集羣節點 IP,這裏需要特別注意一下,如果要對外提供訪問功能,需要填寫宿主機的 IP,如果填寫 Docker 分配的 IP(172.x.x.x),可能會導致外部無法正常訪問集羣;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"cluster-announce-port"}]},{"type":"text","text":":集羣節點映射端口;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"cluster-announce-bus-port"}]},{"type":"text","text":":集羣節點總線端口。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  每個 Redis 集羣節點都需要打開"},{"type":"text","marks":[{"type":"strong"}],"text":"兩個 TCP 連接"},{"type":"text","text":"。一個用於爲客戶端提供服務的正常 Redis TCP 端口,例如 6379。還有一個基於 6379 端口加 10000 的端口,比如 16379。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  第二個端口用於集羣總線,這是一個使用二進制協議的節點到節點通信通道。節點使用集羣總線進行故障檢測、配置更新、故障轉移授權等等。客戶端永遠不要嘗試與集羣總線端口通信,與正常的 Redis 命令端口通信即可,但是請確保防火牆中的這兩個端口都已經打開,否則 Redis 集羣節點將無法通信。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  在 "},{"type":"codeinline","content":[{"type":"text","text":"redis-cluster"}]},{"type":"text","text":" 目錄下執行以下命令:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"for port in `seq 6371 6376`; do \\\n mkdir -p ${port}/conf \\\n && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \\\n && mkdir -p ${port}/data;\\\ndone"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面是一段 shell for 語句,意思就是循環創建 6371 ~ 6376 相關的目錄及文件。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  查看命令執行結果,如果沒有 "},{"type":"codeinline","content":[{"type":"text","text":"tree"}]},{"type":"text","text":" 命令先安裝 "},{"type":"codeinline","content":[{"type":"text","text":"yum install -y tree"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/97/978a3123c8900202d23454c01c181c78.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  以下內容爲每個節點的配置文件詳細信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"[root@localhost redis-cluster]# cat /usr/local/docker-redis/redis-cluster/637{1..6}/conf/redis.conf\nport 6371\nrequirepass 1234\nmasterauth 1234\nprotected-mode no\ndaemonize no\nappendonly yes\ncluster-enabled yes\ncluster-config-file nodes.conf\ncluster-node-timeout 15000\ncluster-announce-ip 192.168.10.10\ncluster-announce-port 6371\ncluster-announce-bus-port 16371\n\nport 6372\nrequirepass 1234\nmasterauth 1234\nprotected-mode no\ndaemonize no\nappendonly yes\ncluster-enabled yes\ncluster-config-file nodes.conf\ncluster-node-timeout 15000\ncluster-announce-ip 192.168.10.10\ncluster-announce-port 6372\ncluster-announce-bus-port 16372\n\nport 6373\nrequirepass 1234\nmasterauth 1234\nprotected-mode no\ndaemonize no\nappendonly yes\ncluster-enabled yes\ncluster-config-file nodes.conf\ncluster-node-timeout 15000\ncluster-announce-ip 192.168.10.10\ncluster-announce-port 6373\ncluster-announce-bus-port 16373\n\nport 6374\nrequirepass 1234\nmasterauth 1234\nprotected-mode no\ndaemonize no\nappendonly yes\ncluster-enabled yes\ncluster-config-file nodes.conf\ncluster-node-timeout 15000\ncluster-announce-ip 192.168.10.10\ncluster-announce-port 6374\ncluster-announce-bus-port 16374\n\nport 6375\nrequirepass 1234\nmasterauth 1234\nprotected-mode no\ndaemonize no\nappendonly yes\ncluster-enabled yes\ncluster-config-file nodes.conf\ncluster-node-timeout 15000\ncluster-announce-ip 192.168.10.10\ncluster-announce-port 6375\ncluster-announce-bus-port 16375\n\nport 6376\nrequirepass 1234\nmasterauth 1234\nprotected-mode no\ndaemonize no\nappendonly yes\ncluster-enabled yes\ncluster-config-file nodes.conf\ncluster-node-timeout 15000\ncluster-announce-ip 192.168.10.10\ncluster-announce-port 6376\ncluster-announce-bus-port 16376"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"創建 Redis 容器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"創建容器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  將宿主機的 "},{"type":"codeinline","content":[{"type":"text","text":"6371 ~ 6376"}]},{"type":"text","text":" 之間的端口與 6 個 Redis 容器映射,並將宿主機的目錄與容器內的目錄進行映射(目錄掛載)。記得指定網絡模式,使用我們自己創建的 "},{"type":"codeinline","content":[{"type":"text","text":"redis-net"}]},{"type":"text","text":" 網絡。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"for port in $(seq 6371 6376); do \\\n docker run -di -p ${port}:${port} -p 1${port}:1${port} \\\n --restart always --name redis-${port} --net redis-net \\\n -v /usr/local/docker-redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \\\n -v /usr/local/docker-redis/redis-cluster/${port}/data:/data \\\n redis redis-server /usr/local/etc/redis/redis.conf; \\\ndone"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "},{"type":"codeinline","content":[{"type":"text","text":"docker ps -n 6"}]},{"type":"text","text":" 查看容器是否創建成功。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/65/65c7a2d40776880113619b35f4aa88ca.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "},{"type":"codeinline","content":[{"type":"text","text":"docker network inspect redis-net | grep -i -E \"name|ipv4address\""}]},{"type":"text","text":" 查看給每個節點分配的IP信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/56/569552c67696cbb8aab1fcf2a8314b7d.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"創建 Redis Cluster 集羣"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  隨便進入一個容器節點,並進入 "},{"type":"codeinline","content":[{"type":"text","text":"/usr/local/bin/"}]},{"type":"text","text":" 目錄:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# 進入容器\ndocker exec -it redis-6371 bash\n# 切換至指定目錄\ncd /usr/local/bin/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  接下來我們就可以通過以下命令實現 Redis Cluster 集羣的創建。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"redis-cli -a 1234 --cluster create 172.18.0.2:6371 172.18.0.3:6372 172.18.0.4:6373 172.18.0.5:6374 172.18.0.6:6375 172.18.0.7:6376 --cluster-replicas 1"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  出現選擇提示信息,輸入 "},{"type":"text","marks":[{"type":"strong"}],"text":"yes"},{"type":"text","text":",結果如下所示:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/84/844c6920f8100e01b1b0538f4edf27e0.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  集羣創建成功如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ce/cee8c8f5666ea3ca91706d46a48a04cd.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  以下內容是創建集羣時返回的詳細信息,也就是上兩幅圖中的所有內容。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"root@705a5ec95a2e:/usr/local/bin# redis-cli -a 1234 --cluster create 172.18.0.2:6371 172.18.0.3:6372 172.18.0.4:6373 172.18.0.5:6374 172.18.0.6:6375 172.18.0.7:6376 --cluster-replicas 1\nWarning: Using a password with '-a' or '-u' option on the command line interface may not be safe.\n>>> Performing hash slots allocation on 6 nodes...\nMaster[0] -> Slots 0 - 5460\nMaster[1] -> Slots 5461 - 10922\nMaster[2] -> Slots 10923 - 16383\nAdding replica 172.18.0.6:6375 to 172.18.0.2:6371\nAdding replica 172.18.0.7:6376 to 172.18.0.3:6372\nAdding replica 172.18.0.5:6374 to 172.18.0.4:6373\nM: 4dbede8f79c98a8cf63556387ce8c2a793d20089 172.18.0.2:6371\n slots:[0-5460] (5461 slots) master\nM: c2117d59666f20be5a29485b2e22753991a2dcb9 172.18.0.3:6372\n slots:[5461-10922] (5462 slots) master\nM: a5a8fdda426785c54a0e557b753ef571d22581a7 172.18.0.4:6373\n slots:[10923-16383] (5461 slots) master\nS: 4aca662dbc0d40498592c11c8dcb94b62c39b15c 172.18.0.5:6374\n replicates a5a8fdda426785c54a0e557b753ef571d22581a7\nS: 55fe2da8fe4fb1acdf950a6030a6304713eb613b 172.18.0.6:6375\n replicates 4dbede8f79c98a8cf63556387ce8c2a793d20089\nS: be84c1e8600986d5ebfbd2e18611dc4d1ace41a7 172.18.0.7:6376\n replicates c2117d59666f20be5a29485b2e22753991a2dcb9\nCan I set the above configuration? (type 'yes' to accept): yes\n>>> Nodes configuration updated\n>>> Assign a different config epoch to each node\n>>> Sending CLUSTER MEET messages to join the cluster\nWaiting for the cluster to join\n\n>>> Performing Cluster Check (using node 172.18.0.2:6371)\nM: 4dbede8f79c98a8cf63556387ce8c2a793d20089 172.18.0.2:6371\n slots:[0-5460] (5461 slots) master\n 1 additional replica(s)\nS: be84c1e8600986d5ebfbd2e18611dc4d1ace41a7 192.168.10.10:6376\n slots: (0 slots) slave\n replicates c2117d59666f20be5a29485b2e22753991a2dcb9\nM: c2117d59666f20be5a29485b2e22753991a2dcb9 192.168.10.10:6372\n slots:[5461-10922] (5462 slots) master\n 1 additional replica(s)\nM: a5a8fdda426785c54a0e557b753ef571d22581a7 192.168.10.10:6373\n slots:[10923-16383] (5461 slots) master\n 1 additional replica(s)\nS: 4aca662dbc0d40498592c11c8dcb94b62c39b15c 192.168.10.10:6374\n slots: (0 slots) slave\n replicates a5a8fdda426785c54a0e557b753ef571d22581a7\nS: 55fe2da8fe4fb1acdf950a6030a6304713eb613b 192.168.10.10:6375\n slots: (0 slots) slave\n replicates 4dbede8f79c98a8cf63556387ce8c2a793d20089\n[OK] All nodes agree about slots configuration.\n>>> Check for open slots...\n>>> Check slots coverage...\n[OK] All 16384 slots covered."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  至此一個高可用的 Redis Cluster 集羣搭建完成,如下圖所示,該集羣中包含 6 個 Redis 節點,3 主 3 從。三個主節點會分配槽,處理客戶端的命令請求,而從節點可用在主節點故障後,頂替主節點。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/27/27ad2d63da3a5939ff37f79c0baa3f49.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"查看集羣狀態"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  我們先進入容器,然後通過一些集羣常用的命令查看一下集羣的狀態。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# 進入容器\ndocker exec -it redis-6371 bash\n# 切換至指定目錄\ncd /usr/local/bin/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"檢查集羣狀態"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  因爲我們使用了自定義的網絡進行容器管理,這樣可以使容器直接通過容器名稱通信。推薦使用這種方式。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# 使用 IP\nredis-cli -a 1234 --cluster check 192.168.10.10:6371\n# 使用容器名稱\nredis-cli -a 1234 --cluster check redis-6372:6372"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/94/94c31410b6a03bebd377a937321f28ef.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"查看集羣信息和節點信息"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# 連接至集羣某個節點\nredis-cli -c -a 1234 -h redis-6373 -p 6373\n# 查看集羣信息\ncluster info\n# 查看集羣結點信息\ncluster nodes"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/19/19fcfd1a639370243688dc338657b224.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"SET/GET"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  在 6371 節點中執行寫入和讀取,命令如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# 進入容器並連接至集羣某個節點\ndocker exec -it redis-6371 /usr/local/bin/redis-cli -c -a 1234 -h redis-6371 -p 6371\n# 寫入數據\nset name mrhelloworld\nset aaa 111\nset bbb 222\n# 讀取數據\nget name\nget aaa\nget bbb"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5e/5e9bc4e5e6a918637c6a0bcc2cb34fac.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  彆着急,讓我來解釋一下上圖中的操作過程:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先進入容器並連接至集羣某個節點;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後執行"},{"type":"text","marks":[{"type":"strong"}],"text":"第一個"},{"type":"text","text":" set 命令 "},{"type":"codeinline","content":[{"type":"text","text":"set name mrhelloworld"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"name"}]},{"type":"text","text":" 鍵根據哈希函數運算以後得到的值爲 "},{"type":"codeinline","content":[{"type":"text","text":"[5798]"}]},{"type":"text","text":"。當前集羣環境的槽分配情況爲:"},{"type":"codeinline","content":[{"type":"text","text":"[0-5460] 6371節點"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"[5461-10922] 6372節點"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"[10923-16383] 6373節點"}]},{"type":"text","text":",所以該鍵的存儲就被分配到了 "},{"type":"text","marks":[{"type":"strong"}],"text":"6372"},{"type":"text","text":" 節點上;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再來看"},{"type":"text","marks":[{"type":"strong"}],"text":"第二個"},{"type":"text","text":" set 命令 "},{"type":"codeinline","content":[{"type":"text","text":"set aaa"}]},{"type":"text","text":",這裏大家可能會有一些疑問,爲什麼看不到 "},{"type":"codeinline","content":[{"type":"text","text":"aaa"}]},{"type":"text","text":" 鍵根據哈希函數運算以後得到的值?因爲剛纔重定向至 "},{"type":"text","marks":[{"type":"strong"}],"text":"6372"},{"type":"text","text":" 節點插入了數據,此時如果還有數據插入,正好鍵根據哈希函數運算以後得到的值也還在該節點的範圍內,那麼直接插入數據即可;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着是"},{"type":"text","marks":[{"type":"strong"}],"text":"第三個"},{"type":"text","text":" set 命令 "},{"type":"codeinline","content":[{"type":"text","text":"set bbb"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"bbb"}]},{"type":"text","text":" 鍵根據哈希函數運算以後得到的值爲 "},{"type":"codeinline","content":[{"type":"text","text":"[5287]"}]},{"type":"text","text":",所以該鍵的存儲就被分配到了 "},{"type":"text","marks":[{"type":"strong"}],"text":"6371"},{"type":"text","text":" 節點上;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後是讀取操作,"},{"type":"text","marks":[{"type":"strong"}],"text":"第四個"},{"type":"text","text":"命令 "},{"type":"codeinline","content":[{"type":"text","text":"get name"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"name"}]},{"type":"text","text":" 鍵根據哈希函數運算以後得到的值爲 "},{"type":"codeinline","content":[{"type":"text","text":"[5798]"}]},{"type":"text","text":",被重定向至 "},{"type":"text","marks":[{"type":"strong"}],"text":"6372"},{"type":"text","text":" 節點讀取;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"第五個"},{"type":"text","text":"命令 "},{"type":"codeinline","content":[{"type":"text","text":"get aaa"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"aaa"}]},{"type":"text","text":" 鍵根據哈希函數運算以後得到的值也在 "},{"type":"text","marks":[{"type":"strong"}],"text":"6372"},{"type":"text","text":" 節點,直接讀取;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"第六個"},{"type":"text","text":"命令 "},{"type":"codeinline","content":[{"type":"text","text":"get bbb"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"bbb"}]},{"type":"text","text":" 鍵根據哈希函數運算以後得到的值爲 "},{"type":"codeinline","content":[{"type":"text","text":"[5287]"}]},{"type":"text","text":",被重定向至 "},{"type":"text","marks":[{"type":"strong"}],"text":"6371"},{"type":"text","text":" 節點讀取。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  通過以上操作我們得知 "},{"type":"codeinline","content":[{"type":"text","text":"name"}]},{"type":"text","text":" 鍵的存儲被分配到了 6372 節點,如果直接連接 6372 節點並獲取該值會怎麼樣?沒錯,不需要重定向節點,因爲數據就在該節點,所以直接讀取返回。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/22/22a8ef10b1895ab2874883a67b4e35b8.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  總結下來就是,在 "},{"type":"text","marks":[{"type":"strong"}],"text":"Redis Cluster 集羣模式"},{"type":"text","text":"中,*"},{"type":"text","marks":[{"type":"italic"}],"text":"無論連接哪個節點"},{"type":"text","text":"*,每次我們"},{"type":"text","marks":[{"type":"strong"}],"text":"執行寫入或者讀取"},{"type":"text","text":"操作的時候,所有的"},{"type":"text","marks":[{"type":"strong"}],"text":"鍵會根據哈希函數運算並映射到 0 ~ 16383 整數槽內"},{"type":"text","text":",如果恰好對應的"},{"type":"text","marks":[{"type":"strong"}],"text":"槽"},{"type":"text","text":"就在你"},{"type":"text","marks":[{"type":"strong"}],"text":"當前連接的節點"},{"type":"text","text":"中,則"},{"type":"text","marks":[{"type":"strong"}],"text":"直接執行"},{"type":"text","text":"命令,"},{"type":"text","marks":[{"type":"strong"}],"text":"否則重定向"},{"type":"text","text":"至對應節點執行命令。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"客戶端連接"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  最後來一波客戶端連接操作,隨便哪個節點,看看可否通過外部訪問 Redis Cluster 集羣。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c9/c92b7339c9633ff015f1ccd8198843a3.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/67/67e313bd75548e98ee916599936b5b98.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  至此使用多個容器搭建 Redis Cluster 集羣環境就到這裏,其實整體搭建過程不算特別麻煩,因爲:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建 Redis 集羣需要用到 Ruby,否則就得自己關聯節點構建集羣,自己分配槽;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果使用 Ruby 構建 Redis 集羣,就需要安裝 Ruby 環境;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而 Redis 從 5 版本開始可以直接使用 "},{"type":"codeinline","content":[{"type":"text","text":"redis-cli"}]},{"type":"text","text":" 命令創建集羣了,就省去了很多麻煩事;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們還使用了 shell for 循環語句簡化了構建過程,否則那些語句一條條執行也夠你鬧心的。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  綜上所述,有沒有更簡單的辦法呢?當然有了,不然我在這跟你賣什麼關子。"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ca/ca6a0cd443ac48cb6049c0c13278eec1.jpeg","alt":null,"title":"","style":[{"key":"width","value":"25%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Docker Compose 就可以解決這個問題。後面我們先學習一下什麼是 Docker Compose,然後使用 Docker Compose 再來搭建一遍 Redis Cluster 集羣環境,感受感受這前後的區別。"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/3f/3f2b7927a66dc6426ff7a6f46f8d35a3.gif","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文采用 "},{"type":"link","attrs":{"href":"http://creativecommons.org/licenses/by-nc-nd/4.0/","title":null},"content":[{"type":"text","text":"知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家可以通過 "},{"type":"link","attrs":{"href":"https://mrhelloworld.com/categories/docker","title":null},"content":[{"type":"text","text":"分類"}]},{"type":"text","text":" 查看更多關於 "},{"type":"link","attrs":{"href":"https://mrhelloworld.com/categories/docker","title":null},"content":[{"type":"text","text":"Docker"}]},{"type":"text","text":" 的文章。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🤗 您的"},{"type":"codeinline","content":[{"type":"text","text":"點贊"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"轉發"}]},{"type":"text","text":"是對我最大的支持。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"📢 掃碼關注 "},{"type":"codeinline","content":[{"type":"text","text":"哈嘍沃德先生"}]},{"type":"text","text":"「文檔 + 視頻」每篇文章都配有專門視頻講解,學習更輕鬆噢 ~"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/67/6739b2ed350171f1bca3a0238715c45f.gif","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1c/1c2456f4fc38ffa2fd1e6c975127550b.jpeg","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章