以前咱們分析過喜馬拉雅的爬取信息,使用分佈式爬取,並且須要修改scrapy-redis的過濾算法爲布隆過濾來減小redis內存佔用,最後考慮這樣仍是不必定夠,那麼redis集羣就是更好的一種選擇方式了。node
Redis 集羣是一個提供在多個Redis節點間共享數據的程序集。python
Redis集羣並不支持處理多個keys的命令,由於這須要在不一樣的節點間移動數據,從而達不到像Redis那樣的性能,在高負載的狀況下可能會致使不可預料的錯誤.redis
Redis 集羣經過分區來提供必定程度的可用性,在實際環境中當某個節點宕機或者不可達的狀況下繼續處理命令. Redis 集羣的優點:算法
自動分割數據到不一樣的節點上。 整個集羣的部分節點失敗或者不可達的狀況下可以繼續處理命令。
Redis 集羣鍵分佈算法使用數據分片(sharding)而非一致性哈希(consistency hashing)來實現: 一個 Redis 集羣包含 16384 個哈希槽(hash slot), 它們的編號爲0、一、二、3……1638二、16383,這個槽是一個邏輯意義上的槽,實際上並不存在。redis中的每一個key都屬於這 16384 個哈希槽的其中一個,存取key時都要進行key->slot的映射計算。數據庫
Redis 集羣有16384個哈希槽,每一個key經過CRC16校驗後對16384取模來決定放置哪一個槽.集羣的每一個節點負責一部分hash槽,舉個例子,好比當前集羣有3個節點,那麼:ruby
節點 A 包含 0 到 5500號哈希槽. 節點 B 包含5501 到 11000 號哈希槽. 節點 C 包含11001 到 16384號哈希槽.
這種結構很容易添加或者刪除節點. 好比若是我想新添加個節點D, 我須要從節點 A, B, C中得部分槽到D上. 若是我想移除節點A,須要將A中的槽移到B和C節點上,而後將沒有任何槽的A節點從集羣中移除便可. 因爲從一個節點將哈希槽移動到另外一個節點並不會中止服務,因此不管添加刪除或者改變某個節點的哈希槽的數量都不會形成集羣不可用的狀態.微信
爲了使在部分節點失敗或者大部分節點沒法通訊的狀況下集羣仍然可用,因此集羣使用了主從複製模型,每一個節點都會有N-1個複製品.網絡
在咱們例子中具備A,B,C三個節點的集羣,在沒有複製模型的狀況下,若是節點B失敗了,那麼整個集羣就會覺得缺乏5501-11000這個範圍的槽而不可用.數據結構
然而若是在集羣建立的時候(或者過一段時間)咱們爲每一個節點添加一個從節點A1,B1,C1,那麼整個集羣便有三個master節點和三個slave節點組成,這樣在節點B失敗後,集羣便會選舉B1爲新的主節點繼續服務,整個集羣便不會由於槽找不到而不可用了app
不過當B和B1 都失敗後,集羣是不可用的.
Redis 並不能保證數據的強一致性. 這意味這在實際中集羣在特定的條件下可能會丟失寫操做.
第一個緣由是由於集羣是用了異步複製. 寫操做過程:
客戶端向主節點B寫入一條命令. 主節點B向客戶端回覆命令狀態. 主節點將寫操做複製給他得從節點 B1, B2 和 B3.
主節點對命令的複製工做發生在返回命令回覆以後, 由於若是每次處理命令請求都須要等待複製操做完成的話, 那麼主節點處理命令請求的速度將極大地下降 —— 咱們必須在性能和一致性之間作出權衡。 注意:Redis 集羣可能會在未來提供同步寫的方法。 Redis 集羣另一種可能會丟失命令的狀況是集羣出現了網絡分區, 而且一個客戶端與至少包括一個主節點在內的少數實例被孤立。
舉個例子 假設集羣包含 A 、 B 、 C 、 A1 、 B1 、 C1 六個節點, 其中 A 、B 、C 爲主節點, A1 、B1 、C1 爲A,B,C的從節點, 還有一個客戶端 Z1 假設集羣中發生網絡分區,那麼集羣可能會分爲兩方,大部分的一方包含節點 A 、C 、A1 、B1 和 C1 ,小部分的一方則包含節點 B 和客戶端 Z1 .
Z1仍然可以向主節點B中寫入, 若是網絡分區發生時間較短,那麼集羣將會繼續正常運做,若是分區的時間足夠讓大部分的一方將B1選舉爲新的master,那麼Z1寫入B中得數據便丟失了.
CentOS和Mac的安裝請看:Linux/Mac安裝Redis數據庫
Linux通用的安裝方式:
mkdir /home/redis-cluster cd /home/redis-cluster # 下載穩定版redis wget http://download.redis.io/releases/redis-stable.tar.gz tar xvf redis-stable.tar.gz cd redis-stable make make install
安裝完之後,redis命令會在/usr/local/bin目錄下,咱們還須要將src/redis-trib.rb文件拷貝到/usr/local/bin目錄下,咱們直接在命令行使用redis-server就能夠啓動服務
在redis-stable目錄下有redis.conf文件,先修改文件配置
port 7000(每一個節點的端口號) daemonize yes(後臺運行) bind 192.168.1.110(綁定當前機器 IP) dir /home/redis-cluster/7000/data/(數據文件存放位置) pidfile /var/run/redis_7000.pid(pid 7000和port要對應) cluster-enabled yes(啓動集羣模式) cluster-config-file nodes-7000.conf(7000和port要對應) cluster-node-timeout 15000 appendonly yes
先建立集羣目錄
cd /home/redis-cluster mkdir -p 7000/data 7001/data 7002/data 7003/data 7004/data 7005/data
將上面的redis.conf文件分別複製到這幾個文件夾中,修改其中端口相關的部分
port 7001 dir /home/redis-cluster/7001/data/ pidfile /var/run/redis_7001.pid pidfile /var/run/redis_7001.pid cluster-config-file nodes-7001.conf
啓動節點
redis-server /home/redis-cluster/7000/data/redis.conf redis-server /home/redis-cluster/7001/data/redis.conf redis-server /home/redis-cluster/7002/data/redis.conf redis-server /home/redis-cluster/7003/data/redis.conf redis-server /home/redis-cluster/7004/data/redis.conf redis-server /home/redis-cluster/7005/data/redis.conf
到這裏先別急,離成功已經很近了,咱們還須要安裝集羣所需的軟件
CentOS安裝
yum install ruby yum install rubygems gem install redis
壓縮包安裝
下載ruby網址:https://www.ruby-lang.org/en/downloads/
下載rubygems網址:https://rubygems.org/pages/download
# 下載ruby wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.gz tar xf ruby-2.5.1.tar.gz cd ruby-2.5.1 ./configure make make install #下載rubygems wget https://rubygems.org/rubygems/rubygems-2.7.7.tgz tar xf rubygems-2.7.7.tgz cd rubygems-2.7.7 ruby setup.rb #安裝完rubygems後,就可使用gem命令安裝redis支持 gem install redis
啓動集羣
redis-trib.rb create --replicas 1 192.168.1.110:7000 192.168.1.110:7001 192.168.1.110:1002 192.168.1.110:7003 192.168.1.110:7004 192.168.1.110:7005
參數:
--replicas 1 表示主從複製比例爲 1:1,即一個主節點對應一個從節點;而後,默認給咱們分配好了每一個主節點和對應從節點服務,以及 solt 的大小,由於在 Redis 集羣中有且僅有 16383 個 solt ,默認狀況會給咱們平均分配,固然你能夠指定,後續的增減節點也能夠從新分配。
咱們如今有六個節點,三個主節點三個從節點,默認最少須要六個節點才能組成集羣。
錯誤日誌:若是報node 192.168.1.xx:7001 is not empty之類的錯誤說明集羣未正確關閉或是存有日誌文件則
針對錯誤信息執行集羣修復命令:./redis-trib.rb fix 192.168.133.128:7001
登陸客戶端進行操做:
redis-cli -c -h 192.168.1.110 -p 7000
必定要加上-c參數
到這裏單機集羣配置已經成功了
與單機配置相比較,須要修改的有如下幾點:
其餘的命令等均同樣
集羣搭建好了,可是有一點要注意,對於同一個key只會存在於一個節點機器上,好比set、zset、list這種數據結構。因此最初我想用集羣去存儲上億條去重數據等想法是不行了。最終仍是要修改去重算法。
python的redis庫是不支持集羣操做的,推薦庫:redis-py-cluster,一直在維護。還有一個rediscluster庫,看GitHub上已經好久沒更新了。
安裝pip install redis-py-cluster
from rediscluster import StrictRedisCluster startup_nodes = [ {"host":"192.168.1.110", "port":7000}, {"host":"192.168.1.110", "port":7001}, {"host":"192.168.1.110", "port":7002}, {"host":"192.168.1.110", "port":7003}, {"host":"192.168.1.110", "port":7004}, {"host":"192.168.1.110", "port":7005} ] rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True) rc.set('name','admin') rc.set('age',18) print "name is: ", rc.get('name') print "age is: ", rc.get('age')
除了鏈接這裏不同,其餘的操做與redis庫一致,另外在startup_nodes參數中即便寫錯幾個機器host或port也能鏈接成功,理論上講只要有一個節點正常就可使用
若是你以爲個人文章還能夠,能夠關注個人微信公衆號,查看更多實戰文章:Python爬蟲實戰之路
也能夠掃描下面二維碼,添加個人微信公衆號