Redis 分布式集群的幾種方案及問題


1、Redis 分布式集群的幾種方案

1.1、主從復制

從服務器連接主服務器,發送SYNC命令; 主服務器接收到SYNC命名后,開始執行BGSAVE命令生成RDB文件並使用緩沖區記錄此后執行的所有寫命令; 主服務器BGSAVE執行完后,向所有從服務器發送快照文件,並在發送期間繼續記錄被執行的寫命令; 從服務器收到快照文件后丟棄所有舊數據,載入收到的快照; 主服務器快照發送完畢后開始向從服務器發送緩沖區中的寫命令; 從服務器完成對快照的載入,開始接收命令請求,並執行來自主服務器緩沖區的寫命令;(從服務器初始化完成)主服務器每執行一個寫命令就會向從服務器發送相同的寫命令,從服務器接收並執行收到的寫命令(從服務器初始化完成后的操作)

主從復制優缺點:

優點:

支持主從復制,主機會自動將數據同步到從機,可以進行讀寫分離為了分載Master的讀操作壓力,Slave服務器可以為客戶端提供只讀操作的服務,寫服務仍然必須由Master來完成Slave同樣可以接受其它Slaves的連接和同步請求,這樣可以有效的分載Master的同步壓力。Master Server是以非阻塞的方式為Slaves提供服務。所以在Master-Slave同步期間,客戶端仍然可以提交查詢或修改請求。Slave Server同樣是以非阻塞的方式完成數據同步。在同步期間,如果有客戶端提交查詢請求,Redis則返回同步之前的數據

缺點:

Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復。主機宕機,宕機前有部分數據未能及時同步到從機,切換IP后還會引入數據不一致的問題,降低了系統的可用性。Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜。

1.2、 哨兵模式

當主服務器中斷服務后,可以將一個從服務器升級為主服務器,以便繼續提供服務,但是這個過程需要人工手動來操作。 為此,Redis 2.8中提供了哨兵工具來實現自動化的系統監控和故障恢復功能。

哨兵的作用就是監控Redis系統的運行狀況。它的功能包括以下兩個。
(1)監控主服務器和從服務器是否正常運行。
(2)主服務器出現故障時自動將從服務器轉換為主服務器。

哨兵的工作方式:

每個Sentinel(哨兵)進程以每秒鍾一次的頻率向整個集群中的Master主服務器,Slave從服務器以及其他Sentinel(哨兵)進程發送一個 PING 命令。如果一個實例(instance)距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被 Sentinel(哨兵)進程標記為主觀下線(SDOWN)如果一個Master主服務器被標記為主觀下線(SDOWN),則正在監視這個Master主服務器的所有 Sentinel(哨兵)進程要以每秒一次的頻率確認Master主服務器的確進入了主觀下線狀態當有足夠數量的 Sentinel(哨兵)進程(大於等於配置文件指定的值)在指定的時間范圍內確認Master主服務器進入了主觀下線狀態(SDOWN), 則Master主服務器會被標記為客觀下線(ODOWN)在一般情況下, 每個 Sentinel(哨兵)進程會以每 10 秒一次的頻率向集群中的所有Master主服務器、Slave從服務器發送 INFO 命令。當Master主服務器被 Sentinel(哨兵)進程標記為客觀下線(ODOWN)時,Sentinel(哨兵)進程向下線的 Master主服務器的所有 Slave從服務器發送 INFO 命令的頻率會從 10 秒一次改為每秒一次。若沒有足夠數量的 Sentinel(哨兵)進程同意 Master主服務器下線, Master主服務器的客觀下線狀態就會被移除。若 Master主服務器重新向 Sentinel(哨兵)進程發送 PING 命令返回有效回復,Master主服務器的主觀下線狀態就會被移除。

哨兵模式的優缺點

優點:

哨兵模式是基於主從模式的,所有主從的優點,哨兵模式都具有。
主從可以自動切換,系統更健壯,可用性更高。

缺點:

Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜。

1.3、Redis-Cluster集群

redis的哨兵模式基本已經可以實現高可用,讀寫分離 ,但是在這種模式下每台redis服務器都存儲相同的數據,很浪費內存,所以在redis3.0上加入了cluster模式,實現的redis的分布式存儲,也就是說每台redis節點上存儲不同的內容。

Redis-Cluster采用無中心結構,它的特點如下:

所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬。
節點的fail是通過集群中超過半數的節點檢測失效時才生效。
客戶端與redis節點直連,不需要中間代理層.客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可。

工作方式:

在redis的每一個節點上,都有這么兩個東西,一個是插槽(slot),它的的取值范圍是:0-16383。還有一個就是cluster,可以理解為是一個集群管理的插件。當我們的存取的key到達的時候,redis會根據crc16的算法得出一個結果,然后把結果對 16384 求余數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,通過這個值,去找到對應的插槽所對應的節點,然后直接自動跳轉到這個對應的節點上進行存取操作。

為了保證高可用,redis-cluster集群引入了主從模式,一個主節點對應一個或者多個從節點,當主節點宕機的時候,就會啟用從節點。當其它主節點ping一個主節點A時,如果半數以上的主節點與A通信超時,那么認為主節點A宕機了。如果主節點A和它的從節點A1都宕機了,那么該集群就無法再提供服務了。

2、Redis 和數據庫同步、緩沖穿透、雪崩問題、hyperloglog slowqery 實現原理?

2.1、Redis數據庫同步

捕捉所有mysql的修改,寫入和刪除事件,對redis進行操作

2.2、緩沖穿透

用戶想要查詢一個數據,發現redis內存數據庫沒有,也就是緩存沒有命中,於是向持久層數據庫查詢。發現也沒有,於是本次查詢失敗。當用戶很多的時候,緩存都沒有命中,於是都去請求了持久層數據庫。這會給持久層數據庫造成很大的壓力,這時候就相當於出現了緩存穿透。

2.3、雪崩

緩存雪崩是指,緩存層出現了錯誤,不能正常工作了。於是所有的請求都會達到存儲層,存儲層的調用量會暴增,造成存儲層也會掛掉的情況。

2.4、hyperloglog

優點:在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定 的、並且是很小的。(在 Redis 里面,每個 HyperLogLog 鍵只需要花費 12 KB 內存,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費內存就越多的集合形成鮮明對比。)
缺點: HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個元素。

3、100W並發4G數據,10W並發400G數據,如何設計Redis存儲方式?

淘汰策略
存儲吃緊的一個重要原因在於每天會有很多新數據入庫,所以及時清理數據尤為重要。主要方法就是發現和保留熱數據淘汰冷數據。

網民的量級遠遠達不到幾十億的規模,id有一定的生命周期,會不斷的變化。所以很大程度上我們存儲的id實際上是無效的。而查詢其實前端的邏輯就是廣告曝光,跟人的行為有關,所以一個id在某個時間窗口的(可能是一個campaign,半個月、幾個月)訪問行為上會有一定的重復性。

數據初始化之前,我們先利用hbase將日志的id聚合去重,划定TTL的范圍,一般是35天,這樣可以砍掉近35天未出現的id。另外在Redis中設置過期時間是35天,當有訪問並命中時,對key進行續命,延長過期時間,未在35天出現的自然淘汰。這樣可以針對穩定cookie或id有效,實際證明,續命的方法對idfa和imei比較實用,長期積累可達到非常理想的命中。

減少膨脹
Hash表空間大小和Key的個數決定了沖突率(或者用負載因子衡量),再合理的范圍內,key越多自然hash表空間越大,消耗的內存自然也會很大。再加上大量指針本身是長整型,所以內存存儲的膨脹十分可觀。先來談談如何把key的個數減少。

大家先來了解一種存儲結構。我們期望將key1=>value1存儲在redis中,那么可以按照如下過程去存儲。先用固定長度的隨機散列md5(key)值作為redis的key,我們稱之為BucketId,而將key1=>value1存儲在hashmap結構中,這樣在查詢的時候就可以讓client按照上面的過程計算出散列,從而查詢到value1。

過程變化簡單描述為:get(key1) -> hget(md5(key1), key1) 從而得到value1。

如果我們通過預先計算,讓很多key可以在BucketId空間里碰撞,那么可以認為一個BucketId下面掛了多個key。比如平均每個BucketId下面掛10個key,那么理論上我們將會減少超過90%的redis key的個數。

具體實現起來有一些麻煩,而且用這個方法之前你要想好容量規模。我們通常使用的md5是32位的hexString(16進制字符),它的空間是128bit,這個量級太大了,我們需要存儲的是百億級,大約是33bit,所以我們需要有一種機制計算出合適位數的散列,而且為了節約內存,我們需要利用全部字符類型(ASCII碼在0~127之間)來填充,而不用HexString,這樣Key的長度可以縮短到一半。

下面是具體的實現方式

public static byte [] getBucketId(byte [] key, Integer bit) {

    MessageDigest mdInst = MessageDigest.getInstance("MD5");
    mdInst.update(key);
    byte [] md = mdInst.digest();
    byte [] r = new byte[(bit-1)/7 + 1];// 因為一個字節中只有7位能夠表示成單字符
    int a = (int) Math.pow(2, bit%7)-2;
    md[r.length-1] = (byte) (md[r.length-1] & a);
    System.arraycopy(md, 0, r, 0, r.length);

    for(int i=0;i<r.length;i++) {
        if(r[i]<0) r[i] &= 127;
    }
        return r;
}
 

參數bit決定了最終BucketId空間的大小,空間大小集合是2的整數冪次的離散值。這里解釋一下為何一個字節中只有7位可用,是因為redis存儲key時需要是ASCII(0~127),而不是byte array。如果規划百億級存儲,計划每個桶分擔10個kv,那么我們只需2^30=1073741824的桶個數即可,也就是最終key的個數。

減少碎片
碎片主要原因在於內存無法對齊、過期刪除后,內存無法重新分配。通過上文描述的方式,我們可以將人口標簽和mapping數據按照上面的方式去存儲,這樣的好處就是redis key是等長的。另外對於hashmap中的key我們也做了相關優化,截取cookie或者deviceid的后六位作為key,這樣也可以保證內存對齊,理論上會有沖突的可能性,但在同一個桶內后綴相同的概率極低(試想id幾乎是隨機的字符串,隨意10個由較長字符組成的id后綴相同的概率*桶樣本數=發生沖突的期望值<<0.05,也就是說出現一個沖突樣本則是極小概率事件,而且這個概率可以通過調整后綴保留長度控制期望值)。而value只存儲age、gender、geo的編碼,用三個字節去存儲。

另外提一下,減少碎片還有個很low但是有效的方法,將slave重啟,然后強制的failover切換主從,這樣相當於給master整理的內存的碎片。

推薦Google-tcmalloc, facebook-jemalloc內存分配,可以在value不大時減少內存碎片和內存消耗。有人測過大value情況下反而libc更節約。

md5散列桶的方法需要注意的問題

1)kv存儲的量級必須事先規划好,浮動的范圍大概在桶個數的十到十五倍,比如我就想存儲百億左右的kv,那么最好選擇30bit31bit作為桶的個數。也就是說業務增長在一個合理的范圍(1015倍的增長)是沒問題的,如果業務太多倍數的增長,會導致hashset增長過快導致查詢時間增加,甚至觸發zip-list閾值,導致內存急劇上升。

2)適合短小value,如果value太大或字段太多並不適合,因為這種方式必須要求把value一次性取出,比如人口標簽是非常小的編碼,甚至只需要3、4個bit(位)就能裝下。

3)典型的時間換空間的做法,由於我們的業務場景並不是要求在極高的qps之下,一般每天億到十億級別的量,所以合理利用CPU租值,也是十分經濟的。

4)由於使用了信息摘要降低了key的大小以及約定長度,所以無法從redis里面random出key。如果需要導出,必須在冷數據中導出。

5)expire需要自己實現,目前的算法很簡單,由於只有在寫操作時才會增加消耗,所以在寫操作時按照一定的比例抽樣,用HLEN命中判斷是否超過15個entry,超過才將過期的key刪除,TTL的時間戳存儲在value的前32bit中。

6)桶的消耗統計是需要做的。需要定期清理過期的key,保證redis的查詢不會變慢。

4、Redis消息隊列消息實現原理是什么?

redis設計用來做緩存的,但是由於它自身的某種特性使得它可以用來做消息隊列,它有幾個阻塞式的API可以使用,正是這些阻塞式的API讓其有能力做消息隊列;另外,做消息隊列的其他特性例如FIFO(先入先出)也很容易實現,只需要一個list對象從頭取數據,從尾部塞數據即可;redis能做消息隊列還得益於其list對象blpop brpop接口以及Pub/Sub(發布/訂閱)的某些接口,它們都是阻塞版的,所以可以用來做消息隊列。

5、兩個線程交替打印0~100的奇偶

using System;
using System.Threading;
namespace LeeCarry
{
    public class Test
    {
        public static EventWaitHandle oddFlag=new EventWaitHandle(false,EventResetMode.AutoReset);
        public static EventWaitHandle evenFlag=new EventWaitHandle(false,EventResetMode.AutoReset);

        public static void Main(string[] args)
        {
            Thread oddThread=new Thread(OddThread);
            Thread evenThread=new Thread(EvenThread);
            evenThread.Start(); 
            oddThread.Start();
                      
        }
        
        private static void EvenThread()
        {
            for(int i=0;i<=100;i+=2)
            {
                Console.WriteLine("線程1:{0}",i);
                oddFlag.Set();
                evenFlag.WaitOne();
            }
            oddFlag.Set();//最后開一次綠燈防止線程一直被阻塞,也可以在waitone加時間參數
        }
        
        private static void OddThread()
        {
            oddFlag.WaitOne();//確保偶數線程先運行
            for(int i=1;i<=100;i+=2)
            {
                Console.WriteLine("線程2:{0}",i);
                evenFlag.Set();
                oddFlag.WaitOne();
            }
            evenFlag.Set();//最后開一次綠燈防止線程一直被阻塞,也可以在waitone加時間參數
        }
    }
}
 

6、高並發系統,一般需要怎么做

分布式
提升並發的最好的辦法,便是提升硬件。舉個大家都熟悉的例子,十年前的諾基亞手機,一般我們只能簡單的掛一個QQ后台,多干幾個事情,就不行了。五年前,我們用的安卓手機能開十來個任務,切換也比較流暢了,而今天,剛剛發布的蘋果iPhone11,性能就更加強勁。但是我們也發現,這兩年,好像手機的性能沒有飛速發展了。無論是蘋果、高通還是華為,或者是PC芯片的廠商因特爾或者AMD,都開始慢慢在擠牙膏了。這其實是受到物理定理的制約,晶體管不可能無限小,無限集成,硬件不可能一直保持突飛猛進。並且,越是高端的機器,成本越貴,並且這個價格很可能是指數級增長的。谷歌公司在很早之前就發現,於是開始組建分布式系統,使用一個集群而不是一台機器來完成相關的工作,憑借這一點,谷歌在互聯網早期迅速發展。
緩存
緩存,是解決高並發問題的另一個有效手段。因為磁盤的讀寫速度較慢,所以我們常常用讀寫速度的更高的內存來防止流量到達磁盤。一般我們會把一些靜態資源都放在緩存上,或者將一些動態的又不怎么重要的更新頻率可以接受延遲的放在緩存里。舉個例子,音樂服務器,我們可以把專輯的圖片、音樂文件這些放在CDN等緩存服務上,對於一些熱門的評論列表,我們也可以進行緩存,一定時間才刷新一次,可以大大減少磁盤的壓力。當然,有時候有緩存還遠遠不夠,例如前幾天周傑倫的新專輯照樣打垮了QQ音樂的服務器。
異步
即便是有緩存,有些請求仍然沒有辦法快速的響應。有些請求是寫請求,舉個例子,沙茶敏寫了一份電子郵件,群發了1萬個人,群發的人數非常多,服務器要往很多人的信箱投遞消息,假設一個人需要0.1秒,1萬個人也要1000秒。雖然可以並發到多台機器解決,但是非常浪費資源,如果很多人這么做,系統壓力非常大。另外的情況,是有可能某個系統處理非常慢,這個系統既有可能是業務非常復雜,也有可能是第三方系統,舉個例子,沙茶敏從支付寶提取一筆資金到某小銀行,因為技術原因,某個小銀行每次接口訪問都要10秒鍾,不可能在轉賬頁面卡10秒,所以支付寶先告訴用戶轉賬成功了,然后異步進行。異步,我們通常采用了異步隊列,異步的好處除了削峰,限流,提升用戶體驗,還能很好的保護系統。

7、分布式系統怎么做服務治理

針對互聯網業務的特點,eg 突發的流量高峰、網絡延時、機房故障等,重點針對大規模跨機房的海量服務進行運行態治理,保障線上服務的高SLA,滿足用戶的體驗,常用的策略包括限流降級、服務嵌入遷出、服務動態路由和灰度發布等

8、對分布式事務的理解

本質上來說,分布式事務就是為了保證不同數據庫的數據一致性。
事務的ACID特性 原子性 一致性 隔離性 持久性
消息事務+最終一致性

CC提供了一個編程框架,將整個業務邏輯分為三塊:Try、Confirm和Cancel三個操作。以在線下單為例,Try階段會去扣庫存,Confirm階段則是去更新訂單狀態,如果更新訂單失敗,則進入Cancel階段,會去恢復庫存。總之,TCC就是通過代碼人為實現了兩階段提交,不同的業務場景所寫的代碼都不一樣,復雜度也不一樣,因此,這種模式並不能很好地被復用。

9、如何實現負載均衡,有哪些算法可以實現?

經常會用到以下四種算法:隨機(random)、輪訓(round-robin)、一致哈希(consistent-hash)和主備(master-slave)。

10、分布式集群下如何做到唯一序列號

Redis生成ID 這主要依賴於Redis是單線程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY來實現。

11、.net 多線程的四種實現方式

11.1、Thread類創建多線程

/// <summary>
/// Thread類啟動
/// </summary>
public static void Thread_Start()
{
    Thread thread = new Thread(new ParameterizedThreadStart(AddA));
    thread.Start("Thread");
}

11.2、委托方式創建多線程

delegate void Delegate_Add(Object stateInfo);
/// <summary>
/// 委托方式啟動
/// </summary>
public static void Delegate_Start()
{
    Delegate_Add dele_add = AddA;
    dele_add.BeginInvoke("Delegate", null,null);
}
 

11.3、ThreadPool類創建多線程

/// <summary>
/// 線程池方式啟動
/// </summary>
public static void ThreadPool_Start()
{
    WaitCallback w = new WaitCallback(AddA);
    ThreadPool.QueueUserWorkItem(w,"ThreadPool");
}

11.4、Task類創建多線程

/// <summary>
/// Task方式啟動
/// </summary>
public static void Task_Start()
{
    Action<object> add_Action = AddA;
    Task task = new Task(add_Action, "Task");
    task.Start();
}

12、數組、鏈表、哈希、隊列、棧數據結構特點,各自優點和缺點

數組(Array):
優點:查詢快,通過索引直接查找;有序添加,添加速度快,允許重復;
缺點:在中間部位添加、刪除比較復雜,大小固定,只能存儲一種類型的數據;
如果應用需要快速訪問數據,很少插入和刪除元素,就應該用數組。

鏈表(LinkedList):
優點:有序添加、增刪改速度快,對於鏈表數據結構,增加和刪除只要修改元素中的指針就可以了;
缺點:查詢慢,如果要訪問鏈表中一個元素,就需要從第一個元素開始查找;
如果應用需要經常插入和刪除元素,就應該用鏈表。

棧(Stack):
優點:提供后進先出的存儲方式,添加速度快,允許重復;
缺點:只能在一頭操作數據,存取其他項很慢;

隊列(Queue):
優點:提供先進先出的存儲方式,添加速度快,允許重復;
缺點:只能在一頭添加,另一頭獲取,存取其他項很慢;

哈希(Hash):
特點:散列表,不允許重復;
優點:如果關鍵字已知則存取速度極快;
缺點:如果不知道關鍵字則存取很慢,對存儲空間使用不充分;

13、應用程序池集成模式和經典模式的區別

  • 如果托管應用程序在采用集成模式的應用程序池中知運行,服務器將使用 IIS 和 ASP.NET 的集成請求處理管道來處理請求。
  • 如果托管應用程序在采用經典模式的應用程序池中運行,服務器會繼續通過 Aspnet_isapi.dll
    路由托管代碼請求,其處理請求的方式就像應用程序在 IIS 6.0 中運行一樣。

14、垃圾回收的基本原理

回收分為兩個階段: 標記 –> 壓縮

標記的過程,其實就是判斷對象是否可達的過程。當所有的根都檢查完畢后,堆中將包含可達(已標記)與不可達(未標記)對象。
標記完成后,進入壓縮階段。在這個階段中,垃圾回收器線性的遍歷堆,以尋找不可達對象的連續內存塊。並把可達對象移動到這里以壓縮堆。這個過程有點類似於磁盤空間的碎片整理。
在這里插入圖片描述

如上圖所示,綠色框表示可達對象,黃色框為不可達對象。不可達對象清除后,移動可達對象實現內存壓縮(變得更緊湊)。
壓縮之后,“指向這些對象的指針”的變量和CPU寄存器現在都會失效,垃圾回收器必須重新訪問所有根,並修改它們來指向對象的新內存位置。這會造成顯著的性能損失。這個損失也是托管堆的主要缺點。

基於以上特點,垃圾回收引發的回收算法也是一項研究課題。因為如果真等到托管堆滿才開始執行垃圾回收,那就真的太“慢”了。

垃圾回收算法 – 分代(Generation)算法

代是CLR垃圾回收器采用的一種機制,它唯一的目的就是提升應用程序的性能。分代回收,速度顯然快於回收整個堆。

CLR托管堆支持3代:第0代,第1代,第2代。第0代的空間約為256KB,第1代約為2M,第2代約為10M。新構造的對象會被分配到第0代。
在這里插入圖片描述

如上圖所示,當第0代的空間滿時,垃圾回收器啟動回收,不可達對象(上圖C、E)會被回收,存活的對象被歸為第1代。
在這里插入圖片描述

當第0代空間已滿,第1代也開始有很多不可達對象以至空間將滿時,這時兩代垃圾都將被回收。存活下來的對象(可達對象),第0代升為第1代,第1代升為第2代。
實際CLR的代回收機制更加“智能”,如果新創建的對象生存周期很短,第0代垃圾也會立刻被垃圾回收器回收(不用等空間分配滿)。另外,如果回收了第0代,發現還有很多對象“可達”,
並沒有釋放多少內存,就會增大第0代的預算至512KB,回收效果就會轉變為:垃圾回收的次數將減少,但每次都會回收大量的內存。如果還沒有釋放多少內存,垃圾回收器將執行
完全回收(3代),如果還是不夠,則會拋出“內存溢出”異常。
也就是說,垃圾回收器會根據回收內存的大小,動態的調整每一代的分配空間預算!達到自動優化!

總結

垃圾回收背后有這樣一個基本的觀念:編程語言(大多數的)似乎總能訪問無限的內存。而開發者可以一直分配、分配再分配——像魔法一樣,取之不盡用之不竭。
.NET垃圾回收器的基本工作原理是:通過最基本的標記清除原理,清除不可達對象;再像磁盤碎片整理一樣壓縮、整理可用內存;最后通過分代算法實現性能最優化。

15、Redis集群搭建遇到了哪些問題?

1.IP回環地址的問題:
本地建立主從服務器的時候,bind 127.0.0.1是不會有問題;但是如果要建立集群,需要使用機子本身的IP地址。

2.卡在waiting for the cluster to join的問題:
首先檢查IP地址綁定是否正確,如果沒有問題,檢查集群配置文件是否重名:cluster-config-file 這個參數配置后面的文件名稱不能重復。另外appendfilename 這個參數名稱最好每個節點也不一樣

3.連接請求問題:
網上很多文檔說連接請求的命令是 redis-cli -c -p **** ,但是如果不是使用的本地回環,這種鏈接是無法鏈接到集群的,必須在后面加IP地址:redis-cli -c -p **** -h .***.***.

4.配置文件選項前面一定不能有空格

Not all 16384 slots are covered by nodes錯誤
在執行redis-trib.rb create命令創建redis集群的時候,遇到了這個錯誤:Not all 16384 slots are covered by nodes.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM