<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 集群完整性 ``` cluster-require-full-coverage 默認為yes ``` * 為了保證集群完整性,默認情況下當集群**16384個槽任何一個沒有指派到節點時整個集群不可用**。**執行任何鍵命令返回**(error)CLUSTERDOWN Hash slot not served錯誤 * 這是對集群完整性的一種保護措施,保證所有的槽都指派給在線的節點。但是當持有槽的主節點下線時,從故障發現到自動完成轉移期間整個集群是不可用狀態,對于大多數業務無法容忍這種情況, 因此建議**將參數cluster-require-full-coverage配置為no,當主節點故障時只影響它負責槽的相關命令執行,不會影響其他主節點的可用性** ## 帶寬消耗 ![](https://img.kancloud.cn/d8/48/d848dd22f78430ab67c300cc0a2ba7d1_1506x918.png) * 集群內Gossip消息通信本身會消耗帶寬,**官方建議集群最大規模在1000以內**,也是出于對消息通信成本的考慮,因此單集群不適合部署超大規模的節點 * 在之前的文章介紹到,**集群內所有節點通過ping/pong消息彼此交換信息,節點間消息通信對帶寬的消耗體現在以下幾個方面:** * 消息發送頻率:跟cluster-node-timeout密切相關,當節點發現與其他節 點最后通信時間超過cluster-node-timeout/2時會直接發送ping消息 * 消息數據量:每個消息主要的數據占用包含:slots槽數組(2KB空 間)和整個集群1/10的狀態數據(10個節點狀態數據約1KB) * 節點部署的機器規模:機器帶寬的上線是固定的,因此相同規模的集 群分布的機器越多每臺機器劃分的節點越均勻,則集群內整體的可用帶寬越高 * 例如,一個總節點數為200的Redis集群,部署在20臺物理機上每臺劃分 10個節點,cluster-node-timeout采用默認15秒,這時ping/pong消息占用帶寬 達到25Mb。如果把cluster-node-timeout設為20,對帶寬的消耗降低到15Mb以 下 * **集群帶寬消耗主要分為:**讀寫命令消耗+Gossip消息消耗。**因此搭建Redis集群時需要根據業務數據規模和消息通信成本做出合理規劃:** * **1)在滿足業務需要的情況下盡量避免大集群**。同一個系統可以針對不 同業務場景拆分使用多套集群。這樣每個集群既滿足伸縮性和故障轉移要求,還可以規避大規模集群的弊端。如筆者維護的一個推薦系統,根據數據 特征使用了5個Redis集群,每個集群節點規模控制在100以內 * 2)**適度提高cluster-node-timeout降低消息發送頻率,同時cluster-nodetimeout還影響故障轉移的速度**,因此需要根據自身業務場景兼顧二者的平衡 * **3)如果條件允許集群盡量均勻部署在更多機器上**。避免集中部署,如集群有60個節點,集中部署在3臺機器上每臺部署20個節點,這時機器帶寬 消耗將非常嚴重 ## Pub/Sub廣播 * Redis在2.0版本提供了Pub/Sub(發布/訂閱)功能,用于針對頻道實現 消息的發布和訂閱。但是在集群模式下內部實現對所有的publish命令都會向 所有的節點進行廣播,造成每條publish數據都會在集群內所有節點傳播一 次,加重帶寬負擔,如圖所示: ![](https://img.kancloud.cn/c4/34/c4348f8be7a61d8179d164fdeded49fb_608x409.png) * 針對集群模式下publish廣播問題,需要引起開發人員注意,當頻繁應用 Pub/Sub功能時應該避免在大量節點的集群內使用,否則會嚴重消耗集群內網絡帶寬。針對這種情況**建議使用sentinel結構專門用于Pub/Sub功能,**從而規避這一問題 ## 數據傾斜 * 集群傾斜指不同節點之間數據量和請求量出現明顯差異,這種情況將加大負載均衡和開發運維的難度。因此需要理解哪些原因會造成集群傾斜,從 而避免這一問題 ### ①數據傾斜 * **數據傾斜主要分為以下幾種:** * **節點和槽分配嚴重不均** * **不同槽對應鍵數量差異過大** * **集合對象包含大量元素** * **內存相關配置不一致** * **1)節點和槽分配嚴重不均**。針對每個節點分配的槽不均的情況,可以使用redis-trib.rb info {host:ip}進行定位,命令如下: ``` ? bin redis-cli --cluster info 127.0.0.1:7000 127.0.0.1:7000 (e4bba455...) -> 0 keys | 6493 slots | 1 slaves. 127.0.0.1:7001 (26cdec41...) -> 0 keys | 6459 slots | 1 slaves. 127.0.0.1:7002 (86ebe5a5...) -> 2 keys | 3432 slots | 1 slaves. ``` * 以上信息列舉出每個節點負責的槽和鍵總量以及每個槽平均鍵數量。當節點對應槽數量不均勻時,可以使用redis --cluster? rebalance命令進行平衡(謹慎使用,雖然有智能客戶端,但是計劃好了再操作): ``` ? bin redis-cli --cluster rebalance 127.0.0.1:7000 >>> Performing Cluster Check (using node 127.0.0.1:7000) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. >>> Rebalancing across 3 nodes. Total weight = 3.00 ``` 效果: ``` ? bin redis-cli --cluster info 127.0.0.1:7000 127.0.0.1:7000 (e4bba455...) -> 0 keys | 5461 slots | 1 slaves. 127.0.0.1:7001 (26cdec41...) -> 0 keys | 5461 slots | 1 slaves. 127.0.0.1:7002 (86ebe5a5...) -> 2 keys | 5462 slots | 1 slaves. ``` * **2)不同槽對應鍵數量差異過大**。鍵通過CRC16哈希函數映射到槽上, 正常情況下槽內鍵數量會相對均勻。但當大量使用hash\_tag時,會產生不同 的鍵映射到同一個槽的情況。特別是選擇作為hash\_tag的數據離散度較差時,將加速槽內鍵數量傾斜情況。通過命令:cluster countkeysinslot{slot}可 以獲取槽對應的鍵數量,識別出哪些槽映射了過多的鍵。再通過命令cluster getkeysinslot{slot}{count}循環迭代出槽下所有的鍵。從而發現過度使用 hash\_tag的鍵。 * **3)集合對象包含大量元素**。對于大集合對象的識別可以使用redis-cli-- bigkeys命令識別,具體使用見后面“尋找熱點key”的文章。找出大集合之后可以根據業務場景進 行拆分。同時集群槽數據遷移是對鍵執行migrate操作完成,過大的鍵集合如 幾百兆,容易造成migrate命令超時導致數據遷移失敗 * **4)內存相關配置不一致**。內存相關配置指hash-max-ziplist-value、setmax-intset-entries等壓縮數據結構配置。當集群大量使用hash、set等數據結構 時,如果內存壓縮數據結構配置不一致,極端情況下會相差數倍的內存,從而造成節點內存量傾斜; ### ②請求傾斜 * 集群內**特定節點請求量/流量過大將導致節點之間負載不均**,影響集群均衡和運維成本。常出現在熱點鍵場景,當鍵命令消耗較低時如小對象的 get、set、incr等,即使請求量差異較大一般也不會產生負載嚴重不均。但是當**熱點鍵對應高算法復雜度的命令或者是大對象操作如hgetall、smembers等,會導致對應節點負載過高**的情況 * **避免方式如下:** * 1)合理設計鍵,熱點大集合對象做拆分或使用hmget替代hgetall避免整 體讀取 * 2)不要使用熱鍵作為hash_tag,避免映射到同一槽 * 3)對于一致性要求不高的場景,客戶端可使用本地緩存減少熱鍵調 用 ## 讀寫分離 使用cluster進行讀寫分離的成本是非常高的,需要手動去實現一個這樣的客戶端,不如多加節點規模; ### 只讀連接 * **集群模式下從節點不接受任何讀寫請求,**發送過來的鍵命令會重定向到負責槽的主節點上(其中包括它的主節點) * **readonly命令(只讀模式):** * 當需要使用從節點分擔主節點讀壓力時,可以**使用readonly命令打開客戶端連接只讀狀態**。之前的復制配置slave-read-only在集群模式下無效 * 當開啟只讀狀態時,從節點接收讀命令處理流程變為:**如果對應的槽屬于自己正在復制的主節點則直接執行讀命令,否則返回重定向信息** ``` ? ~ redis-cli -c -p 7003 //連接的是從節點 127.0.0.1:7003> get hello -> Redirected to slot [866] located at 127.0.0.1:7002 //但是重定向到了相關的主節點 "wrold" 127.0.0.1:7002> ``` ``` ? ~ redis-cli -c -p 7003 127.0.0.1:7003> readonly //進行readonly,每次讀的時候都需要輸入 OK 127.0.0.1:7003> get hello "wrold" //直接從從節點返回結果了,并沒有重定向 ``` * **readonly命令是連接級別生效,**因此每次新建連接時都需要執行readonly開啟只讀狀態。執行readwrite命令可以關閉連接只讀狀態 ### 讀寫分離 * **集群模式下的讀寫分離,同樣會遇到:**復制延遲,讀取過期數據,從節點故障等問題(具體細節見前面“復制”一系列文章) * **針對從節點故障問題,客戶端需要維護可用節點列表,**集群提供了cluster slaves {nodeId}命令,返回nodeId對應主節點下所有從節點信息,數據格式同cluster nodes,命令如下: ``` ? ~ redis-cli -p 7000 cluster slaves 26cdec411e03740e81741fd1af56c84a8995e1bf 1) "4c0dcdf4862435f9e0b7ab9573c5d88ebce69c9e 127.0.0.1:7005@17005 slave 26cdec411e03740e81741fd1af56c84a8995e1bf 0 1606207496756 15 connected" ``` * **解析以上從節點列表信息,排除fail狀態節點,**這樣客戶端對從節點的故障判定可以委托給集群處理,簡化維護可用從節點列表難度 * **開發提示:**集群模式下讀寫分離涉及對客戶端修改如下: * 1)維護每個主節點可用從節點列表 * 2)針對讀命令維護請求節點路由 * 3)從節點新建連接開啟readonly狀態 * 集群模式下讀寫分離成本比較高,可以直接擴展主節點數量提高集群性能,**一般不建議集群模式下做讀寫分離** * **集群讀寫分離有時用于特殊業務場景如:** * 1)利用復制的最終一致性使用多個從節點做跨機房部署降低讀命令網絡延遲 * 2)主節點故障轉移時間過長,業務端把讀請求路由給從節點保證讀操作可用 * 以上場景也可以在不同機房獨立部署Redis集群解決,通過客戶端多寫來維護,讀命令直接請求到最近機房的Redis集群,或者當一個集群節點故 障時客戶端轉向另一個集群 ## 離線/在線數據遷移 * 應用Redis集群時,常需要**把單機Redis數據遷移到集群環境** * **redis-cli --cluster命令提供了導入功能,**用于數據從單機向集群環境遷移的場景,命令如下: ``` redis-cli import host:port --cluster-from <arg> --cluster-copy --cluster-replace ``` * **上面的命令內部采用批量scan和migrate的方式遷移數據。這種遷移方式存在以下缺點:** * 1)遷移只能從單機節點向集群環境導入數據 * 2)不支持在線遷移數據,遷移數據時應用方必須停寫,無法平滑遷移數據 * 3)遷移過程中途如果出現超時等錯誤,不支持斷點續傳只能重新全量導入 * 4)使用單線程進行數據遷移,大數據量遷移速度過慢 * **正因為這些問題,社區開源了很多遷移工具**,這里推薦一款唯品會開發的redis-migrate-tool,該工具可滿足大多數Redis遷移需求,特點如下: * 支持單機、Twemproxy、Redis Cluster、RDB/AOF等多種類型的數據遷移 * 工具模擬成從節點基于復制流遷移數據,從而支持在線遷移數據,業務方不需要停寫 * 采用多線程加速數據遷移過程且提供數據校驗和查看遷移狀態等功 能 * 更多細節見GitHub:[https://github.com/vipshop/redis-migrate-tool](https://github.com/vipshop/redis-migrate-tool) ## 集群VS單機對比 ### 集群限制 1. key批量操作支持有限:例如mget,mset必須在一個slot; 2. key事務和Lua支持有限:操作的key必須在一個節點; 3. key是數據分區的最小粒度:不支持bigkey分區; 4. 不支持多個數據庫:集群下只有一個db0; 5. 復制只支持一層:不支持樹形復制結構; ### 分布式Redis不一定好 1. Redis cluster:滿足容量和性能的擴展性,很多業務"不需要": 1.大多數時客戶端性能會'降低' 2.命令無法跨節點使用:mget,keys,scan,flush,sinter等; 3.Lua和事務無法跨節點使用; 4.客戶端維護更復雜:SDK和應用本身消耗(例如更多的連接池) 2. 很多場景Redis sentinel已經足夠好. 1.業務量不是非常大可以使用; 2.幾萬的OPS已經足夠了;
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看