分區的概念
分區是分割數據到多個Redis實例的處理過程,因此每個實例只保存key的一個子集。
如果只使用一個redis實例時,其中保存了服務器中全部的緩存數據,這樣會有很大風險,如果單台redis服務宕機了將會影響到整個服務。解決的方法就是我們可以采用分片/分區的技術,將原來一台服務器維護的整個緩存,現在換為由多台服務器共同維護內存空間。
分片的實現
說明與分析:
關於redis的安裝參照上一篇,默認安裝好了redis.
思路:采用在一台主機上實現分片的方式,所以只需要在該主機上配置啟動三台redis的實例即可。因為redis默認使用的端口號為6379,所以這里我們分別使用6379、6380以及6381三個端口來實現。
配置:
1. 進入到redis的安裝目錄下,創建一個shard文件夾,然后將redis的配置文件"redis.conf"復制一份,取名為"redis-6379.conf"(作為6379這台實例的配置文件)。然后將該文件移動到shard文件夾下,再將"redis-6379.conf"復制兩份,一個叫"redis-6380.conf"(作為6380這台實例的配置文件),一個叫"redis-6381.conf"(作為6381這台實例的配置文件)。
2. 修改6379這台實例的配置文件,因為端口6379默認就是redis的端口,所以只需要指定該實例的持久化片區(文件)即可。
3. 修改6380實例的配置文件。
- 修改該實例占用的端口為6380
- 修改pid
- 修改dump文件名
4. 修改6381實例的配置文件。
- 修改該實例占用的端口為6381
- 修改pid
- 修改dump文件名
啟動與測試:
1. 啟動3台redis實例
2. 測試
redis分區有兩種方式,對既定的key有不同的方式來選擇這個key存放到哪個實例中,也就是說有不同的系統來映射某個key到某個Redis的服務。
- 最簡單的分區方式為范圍分區,就是映射一定范圍的對象到特定的Redis實例。比如,ID從0到10000的用戶會保存到實例R0,ID從10001到 20000的用戶會保存到R1,以此類推。
- 另外一種方式是hash一致算法實現分區,對key值進行hash一致性計算后得到結果,最終將數據保存到某一台redis實例中,具體的hash一致性算法可以自行百度一下。
說明:測試采用junit寫的測試方法,方法中定義了一個redis分片的連接池,分別添加用於測試的三個節點實例,然后向redis中增加10個記錄並使用Redis Desktop Manager這個工具查看添加結果。
@Test public void test02(){ //定義redis的配置 PoolConfig poolconfig = new PoolConfig(); poolconfig.setMaxTotal(1000); //表示redis的最大連接數——最大1000個線程 poolconfig.setMinIdle(5); //表示最小空閑數量 //定義redis的多個節點機器 List<JedisShardInfo> list = new ArrayList<>(); //為集合添加參數 list.add(new JedisShardInfo("192.168.161.139", 6379)); list.add(new JedisShardInfo("192.168.161.139", 6380)); list.add(new JedisShardInfo("192.168.161.139", 6381)); //定義redis分片連接池 ShardedJedisPool jedisPool = new ShardedJedisPool(poolconfig, list); //獲取連接操作redis ShardedJedis shardedJedis = jedisPool.getResource(); //向redis中添加20個記錄查看分片結果 for(int i = 0; i < 10; i++){ //增加的記錄格式為 key=NUM_i value=i shardedJedis.set("NUM_"+i, ""+i); } }
測試結果:
說明:測試結果發現10個記錄中有1個分到了6379區,3個分到了6380區,另外6個分到了6381區,因為是采用記錄的key值來進行hash一致性算法來確定記錄的存放區域,所以即使重新分區都不會改變記錄的存放地址,所以仍然可以根據key值來獲取到對應的value值。
分區的不足:
- 分區是多台redis共同作用的,如果其中一台出現了宕機現象,則整個分片都將不能使用,雖然是在一定程度上緩減了內存的壓力,但是沒有實現高可用。
- 涉及多個key的操作通常是不被支持的。舉例來說,當兩個set映射到不同的redis實例上時,你就不能對這兩個set執行交集操作。
- 涉及多個key的redis事務不能使用。
- 當使用分區時,數據處理較為復雜,比如你需要處理多個rdb/aof文件,並且從多個實例和主機備份持久化文件。
高可用的解決方案:可以采用哨兵機制實現主從復制從而實現高可用。