高性能网站架构设计之缓存篇(5)- Redis 集群(上)
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
集群技術(shù)是構(gòu)建高性能網(wǎng)站架構(gòu)的重要手段,試想在網(wǎng)站承受高并發(fā)訪問壓力的同時(shí),還需要從海量數(shù)據(jù)中查詢出滿足條件的數(shù)據(jù),并快速響應(yīng),我們必然想到的是將數(shù)據(jù)進(jìn)行切片,把數(shù)據(jù)根據(jù)某種規(guī)則放入多個(gè)不同的服務(wù)器節(jié)點(diǎn),來降低單節(jié)點(diǎn)服務(wù)器的壓力。
上一篇我們講到了 Redis 的主從復(fù)制技術(shù),當(dāng)實(shí)現(xiàn)了多節(jié)點(diǎn)的 master-slave 后,我們也可以把它叫做集群,但我們今天要講的集群主要是利用切片技術(shù)來組建的集群。
集群要實(shí)現(xiàn)的目的是要將不同的 key 分散放置到不同的 redis 節(jié)點(diǎn),這里我們需要一個(gè)規(guī)則或者算法,通常的做法是獲取 key 的哈希值,然后根據(jù)節(jié)點(diǎn)數(shù)來求模,但這種做法有其明顯的弊端,當(dāng)我們需要增加或減少一個(gè)節(jié)點(diǎn)時(shí),會(huì)造成大量的 key 無法命中,這種比例是相當(dāng)高的,所以就有人提出了一致性哈希的概念。
一致性哈希有四個(gè)重要特征:
均衡性:也有人把它定義為平衡性,是指哈希的結(jié)果能夠盡可能分布到所有的節(jié)點(diǎn)中去,這樣可以有效的利用每個(gè)節(jié)點(diǎn)上的資源。
單調(diào)性:對(duì)于單調(diào)性有很多翻譯讓我非常的不解,而我想要的是當(dāng)節(jié)點(diǎn)數(shù)量變化時(shí)哈希的結(jié)果應(yīng)盡可能的保護(hù)已分配的內(nèi)容不會(huì)被重新分派到新的節(jié)點(diǎn)。
分散性和負(fù)載:這兩個(gè)其實(shí)是差不多的意思,就是要求一致性哈希算法對(duì) key 哈希應(yīng)盡可能的避免重復(fù)。
但一致性哈希不是我們今天要介紹的重點(diǎn),因?yàn)?Redis 引入另一種哈希槽(hash slot)的概念。
Redis 集群中內(nèi)置了 16384 個(gè)哈希槽,當(dāng)需要在 Redis 集群中放置一個(gè) key-value 時(shí),redis 先對(duì) key 使用 crc16 算法算出一個(gè)結(jié)果,然后把結(jié)果對(duì) 16384 求余數(shù),這樣每個(gè) key 都會(huì)對(duì)應(yīng)一個(gè)編號(hào)在 0-16383 之間的哈希槽,redis 會(huì)根據(jù)節(jié)點(diǎn)數(shù)量大致均等的將哈希槽映射到不同的節(jié)點(diǎn)。
使用哈希槽的好處就在于可以方便的添加或移除節(jié)點(diǎn)。
當(dāng)需要增加節(jié)點(diǎn)時(shí),只需要把其他節(jié)點(diǎn)的某些哈希槽挪到新節(jié)點(diǎn)就可以了;
當(dāng)需要移除節(jié)點(diǎn)時(shí),只需要把移除節(jié)點(diǎn)上的哈希槽挪到其他節(jié)點(diǎn)就行了;
內(nèi)部機(jī)制,與我何干,對(duì)于我們來說,在新增或移除節(jié)點(diǎn)的時(shí)候不要讓我們先停掉所有的 redis 服務(wù)我就謝天謝地了,這點(diǎn)它做到了。
下面我們就開始動(dòng)手搭建一個(gè) redis 集群來體驗(yàn)一下。
因?yàn)槲覀円獑?dòng)多個(gè) redis 實(shí)例,雖然我們可以直接通過命令行來啟動(dòng),但始終是不怎么方便的,所以我們先來新建三個(gè)實(shí)例目錄,分別是9001,9002,9003,目錄名就是 redis 實(shí)例的端口號(hào)。
我這里已經(jīng)建好了目錄,然后我們把以前編譯過和修改過的 redis-server、redis.conf這兩個(gè)文件分別拷貝到這三個(gè)目錄里面,拷貝完之后就像這樣子了:
我們打開 redis.conf 文件,為了簡單起見,我們只保留下面幾個(gè)配置項(xiàng):
daemonize yes
port 9001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
注意:port 要修改成對(duì)應(yīng)目錄的名字,也就是每個(gè)實(shí)例要有不同的端口。
下面我們分別啟動(dòng)這三個(gè)實(shí)例:
zhaoguihuadediannao:~ zhaogh$ cd applications/dev/redis-cluster
zhaoguihuadediannao:redis-cluster zhaogh$ cd 9001
zhaoguihuadediannao:9001 zhaogh$ ./redis-server ./redis.conf
zhaoguihuadediannao:9003 zhaogh$ cd ../9002
zhaoguihuadediannao:9002 zhaogh$ ./redis-server ./redis.conf
zhaoguihuadediannao:9002 zhaogh$ cd ../9003
zhaoguihuadediannao:9003 zhaogh$ ./redis-server ./redis.conf
zhaoguihuadediannao:9003 zhaogh$?
接下來我們來創(chuàng)建集群,讓三個(gè)實(shí)例互相通訊:
zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb create --replicas 0 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003
>>> Creating cluster
Connecting to node 127.0.0.1:9001: OK
Connecting to node 127.0.0.1:9002: OK
Connecting to node 127.0.0.1:9003: OK
>>> Performing hash slots allocation on 3 nodes...
Using 3 masters:
127.0.0.1:9001
127.0.0.1:9002
127.0.0.1:9003
M: 92c9912cb1ccf657c886ecd839dd32c66efd8762 127.0.0.1:9001
?? slots:0-5460 (5461 slots) master
M: b6d46fcb8b0e6ee373b09a4f2cbcec744d1a259b 127.0.0.1:9002
?? slots:5461-10922 (5462 slots) master
M: 44ab30c7c589ffb15b9b04dd827c72cfaeedacb2 127.0.0.1:9003
?? slots:10923-16383 (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join..
>>> Performing Cluster Check (using node 127.0.0.1:9001)
M: 92c9912cb1ccf657c886ecd839dd32c66efd8762 127.0.0.1:9001
?? slots:0-5460 (5461 slots) master
M: b6d46fcb8b0e6ee373b09a4f2cbcec744d1a259b 127.0.0.1:9002
?? slots:5461-10922 (5462 slots) master
M: 44ab30c7c589ffb15b9b04dd827c72cfaeedacb2 127.0.0.1:9003
?? slots:10923-16383 (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
zhaoguihuadediannao:src zhaogh$?
需要注意的是執(zhí)行?redis-trib.rb 命令需要 ruby 的支持,如果你沒有安裝可以先到?https://rubygems.org/gems/redis?下載,然后離線安裝。
sudo gem install redis-3.0.7.gem --local
下面我們用 redis 自帶的客戶端測試一下:
zhaoguihuadediannao:src zhaogh$ ./redis-cli -c -p 9001
127.0.0.1:9001> get testkey001
-> Redirected to slot [12786] located at 127.0.0.1:9003
(nil)
127.0.0.1:9003> set testkey002 testvalue002
-> Redirected to slot [401] located at 127.0.0.1:9001
OK
127.0.0.1:9001> get testkey002
"testvalue002"
127.0.0.1:9001> set testkey003 testvalue003
OK
127.0.0.1:9001>?
可以看到,雖然我們第一次連接的是9001端口,當(dāng)我們?nèi)カ@取 testkey001 的時(shí)候,redis cluster 自動(dòng)幫我們重定向到 9003 。
當(dāng)我們?cè)?9003 設(shè)置 testkey002 時(shí),redis cluster 又重定向到 9001 。
總的來說, redis 集群部署起來還是非常方便的,遺憾的是,目前幾乎還沒有 c# 的客戶端能很好的支持 redis 集群,真是非常的悲哀,我們期待他們的更新。
下一遍中,我們繼續(xù)討論 redis 集群,比如,如何增加節(jié)點(diǎn),移除節(jié)點(diǎn),重新切片等,敬請(qǐng)期待。
轉(zhuǎn)載于:https://my.oschina.net/epiclight/blog/410409
總結(jié)
以上是生活随笔為你收集整理的高性能网站架构设计之缓存篇(5)- Redis 集群(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CAS SSO对手机应用支持的一种思路
- 下一篇: exchange 2013 lesson