1. 程式人生 > >Redis筆記整理(三):進階操作與高級部分

Redis筆記整理(三):進階操作與高級部分

數據庫 NoSQL Redis

[TOC]


Redis筆記整理(三):進階操作與高級部分

Redis發布訂閱

Redis發布訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。
Redis客戶端可以訂閱任意數量的頻道。
下圖展示了頻道channel1,以及訂閱這個頻道的三個客戶端——client1,client2,client5之間的關系。
當有新消息通過PUBLISH命令發送給頻道channel1時,這個消息就會被發送給訂閱它的三個客戶端:

技術分享圖片

相關操作命令如下:

命令 描述
PSUBSCRIBE pattern [pattern ...] 訂閱一個或多個符合給定模式的頻道
PUSBSUB subcommand [argument [argument...]] 查看訂閱與發布系統狀態
PUBLISH channel message 將消息發送到指定的頻道
PUNSUBSCRIBE [ pattern [pattern ...]] 退訂所有給定模式的頻道
SUBSCRIBE channel [channel ...] 訂閱給定的一個或多個頻道的信息
UNSUBSCRIBE [channel [channel ...]] 指退訂給定的頻道

舉例如下:

創建的訂閱頻道名為redisChat
localhost:6379> SUBSCRIBE redisChat
1) "subscribe"
2) "redisChat
   重新打開一個新的redis客戶端,然後在同一個頻道redisChat發布兩次消息,訂閱者就能接收到相關消息。
127.0.0.1:6379> PUBLISH redisChat "jack is handsome boy"
這時在訂閱端中很快就可以看到該消息。

Redis事務

  Redis事務可以一次執行多個命令,並且帶有以下兩個重要的保證:
   事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。
                          事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。
   事務是一個原子操作:事務中的命令要麽全部被執行,要麽全部都不執行。

   一個事務從開始到執行會經歷三個階段:
      開始事務。
      命令入隊。
      執行事務。

其相關操作命令如下:

命令 描述
DISCARD 取消事務,放棄執行事務塊內的所有命令
EXEC 執行所有事務塊內的命令
MULTI 標記一個事務塊的開始
UNWATCH 取消WATCH命令對所有key的監視
WATCH key [key ...] 監視一個或多個key,如果在事務執行之前這些key被其它命令所改動,那麽事務將被打斷

舉例如下:

uplooking01:7001> get name
"xpleaf"
uplooking01:7001> MULTI
OK
uplooking01:7001> get name
QUEUED
uplooking01:7001> set name yyh
QUEUED
uplooking01:7001> get name
QUEUED
uplooking01:7001> EXEC
1) "xpleaf"
2) OK
3) "yyh"

Redis命令總結

Redis的常用命令主要分為兩個方面、一個是鍵值相關命令、一個是服務器相關命令
1、鍵值相關命令
      keys * 取出當前所有的key
      exists name 查看redis是否有name這個key
      del name 刪除key name
      expire confirm 100 設置confirm這個key100秒過期
      ttl confirm 獲取confirm 這個key的有效時長
      select 0 選擇到0數據庫 redis默認的數據庫是0~15一共16個數據庫
      move confirm 1 將當前數據庫中的key移動到其他的數據庫中,
      persist confirm 移除confirm這個key的過期時間
      randomkey 隨機返回數據庫裏面的一個key
      rename key2 key3 重命名key2 為key3
      type key2 返回key的數據類型
2、服務器相關命令
      ping PONG返回響應是否連接成功
      echo 在命令行打印一些內容
      select 0~15 編號的數據庫
      quit  /exit 退出客戶端
      dbsize 返回當前數據庫中所有key的數量
      info 返回redis的相關信息
      config get dir/* 實時傳儲收到的請求
      flushdb 刪除當前選擇數據庫中的所有key
      flushall 刪除所有數據庫中的數據庫

Redis安全

我們可以通過redis的配置文件設置密碼參數,這樣客戶端連接到redis服務就需要密碼驗證,這樣可以讓你的redis服務更安全。

我們可以通過以下命令查看是否設置了密碼驗證:

uplooking01:7001> config get requirepass
1) "requirepass"
2) ""

默認情況下requirepass參數是空的,這就意味著無需密碼驗證就可以連接到redis服務。如果設置密碼,客戶端連接redis服務就需要密碼驗證。否則無法執行命令,有兩方式完成認證:

可以在連接時就指定密碼:redis-cli -h uplooking03 -a uplooking
也可以先連接,到終端後再認證:auth uplooking

Redis管道與性能測試

   Redis是一種基於客戶端-服務端模型以及請求/響應協議的TCP服務。這意味著通常情況下一個請求會遵循以下步驟:
   客戶端向服務端發送一個查詢請求,並監聽scoket返回,通常是以阻塞模式,等待服務端響應。
   服務端處理命令,並將結果返回給客戶端。
   Redis管道技術可以在服務端末響應時,客戶端可以繼續想服務端發送請求,並最終一次性讀取所有服務端的相應。

下面使用Java代碼來進行測試:

package com.uplooking.bigdata;

import com.uplooking.bigdata.common.util.redis.JedisUtil;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

/**
 * 使用管道和不使用管道的性能測試對比
 */
public class PipelineTest {

    @Test
    public void testPipeline() {
        int count = 10000;
        // 標記不使用管道操作時的開始時間
        long start = System.currentTimeMillis();
        // 不使用管道執行操作
        withoutPipeline(count);
        // 標記不使用管道操作時的結束時間
        long end = System.currentTimeMillis();
        // 輸出不使用管道進行操作時所消耗的時間
        System.out.println("withoutPipeline: " + (end-start));
        // 標記使用管道操作時的開始時間
        start = System.currentTimeMillis();
        // 使用管道執行操作
        usePipeline(count);
        // 標記使用管道操作時的結束時間
        end = System.currentTimeMillis();
        // 輸出使用管道進行操作時所消耗的時間
        System.out.println("usePipeline: " + (end-start));
    }

    private void withoutPipeline(int count) {
        JedisUtil.getJedis();
        Jedis jedis = JedisUtil.getJedis();
        for(int i =0; i < count; i++) {
            jedis.incr("testKey1");
        }
        cleanUp(jedis);
    }

    private void usePipeline(int count) {
        Jedis jedis = JedisUtil.getJedis();
        Pipeline pl = jedis.pipelined();
        for(int i =0; i < count; i++) {
            pl.incr("testKey1");
        }
        pl.sync();
        cleanUp(jedis);
    }

    public void cleanUp(Jedis jedis) {
        JedisUtil.returnJedis(jedis);
    }
}

JedisUtil可以查看前面的代碼,這裏就不再給出。

輸出結果如下:

withoutPipeline: 1935
usePipeline: 60

測試結果還是有明顯的差距,所以多次操作使用pipeline還是有明顯的優勢。

Redis性能測試:讀寫能力查看

 Redis性能測試是通過同時執行多個命令實現的。
語法
  redis-benchmark [option] [option-value]
實例
  以下實例同時執行10000個請求來檢測性能:
  1)、redis-benchmark -n 100000
  2)、redis-benchmark -h localhost -p 6379 -t set,lpush -n 100000 -q

其常見的命令選項如下:

選項 描述 默認值
-h 指定服務器主機名 127.0.0.1
-p 指定服務器端口 6379
-s 指定服務器socket
-c 指定並發連接數 50
-n 指定請求數 10000
-d 以字節的形式指定set/get值的數據大小 2
-k 1=keep alive 0=reconnect 1
-r set/get/incr使用隨機key,sadd使用隨機值
-P 通過管道傳輸<numreq>請求 1
-q 強制退出redis。僅顯示query/sec值
-csv 以CSV格式輸出
-l 生產循環,永久執行測試
-t 僅運行以逗號分割的測試命令列表
-I Idle模式。僅打開N個idle連接並等待

完整測試案例

[uplooking@uplooking01 ~]$ redis-benchmark -h uplooking01 -p 6379 -n 100000 -c 20
====== PING_INLINE ======
  100000 requests completed in 1.29 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.96% <= 1 milliseconds
100.00% <= 1 milliseconds
77459.34 requests per second

====== PING_BULK ======
  100000 requests completed in 1.33 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.95% <= 1 milliseconds
99.96% <= 2 milliseconds
100.00% <= 2 milliseconds
75187.97 requests per second

====== SET ======
  100000 requests completed in 1.29 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.96% <= 1 milliseconds
99.98% <= 2 milliseconds
99.98% <= 4 milliseconds
99.99% <= 5 milliseconds
100.00% <= 5 milliseconds
77339.52 requests per second

====== GET ======
  100000 requests completed in 1.35 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.98% <= 1 milliseconds
100.00% <= 1 milliseconds
74239.05 requests per second

====== INCR ======
  100000 requests completed in 1.29 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.98% <= 1 milliseconds
100.00% <= 1 milliseconds
77279.75 requests per second

====== LPUSH ======
  100000 requests completed in 1.28 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.98% <= 1 milliseconds
100.00% <= 1 milliseconds
77821.02 requests per second

====== RPUSH ======
  100000 requests completed in 1.28 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.94% <= 1 milliseconds
100.00% <= 1 milliseconds
77881.62 requests per second

====== LPOP ======
  100000 requests completed in 1.27 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.99% <= 1 milliseconds
100.00% <= 1 milliseconds
78616.35 requests per second

====== RPOP ======
  100000 requests completed in 1.27 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.92% <= 1 milliseconds
100.00% <= 1 milliseconds
78678.20 requests per second

====== SADD ======
  100000 requests completed in 1.34 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.99% <= 1 milliseconds
100.00% <= 1 milliseconds
74404.77 requests per second

====== SPOP ======
  100000 requests completed in 1.34 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.96% <= 1 milliseconds
100.00% <= 1 milliseconds
74738.41 requests per second

====== LPUSH (needed to benchmark LRANGE) ======
  100000 requests completed in 1.27 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.96% <= 1 milliseconds
100.00% <= 1 milliseconds
78492.93 requests per second

====== LRANGE_100 (first 100 elements) ======
  100000 requests completed in 2.81 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.87% <= 1 milliseconds
99.98% <= 2 milliseconds
100.00% <= 3 milliseconds
35536.61 requests per second

====== LRANGE_300 (first 300 elements) ======
  100000 requests completed in 7.59 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

97.91% <= 1 milliseconds
99.83% <= 2 milliseconds
99.96% <= 3 milliseconds
100.00% <= 4 milliseconds
100.00% <= 4 milliseconds
13166.56 requests per second

====== LRANGE_500 (first 450 elements) ======
  100000 requests completed in 10.27 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

37.79% <= 1 milliseconds
99.54% <= 2 milliseconds
99.91% <= 3 milliseconds
99.97% <= 4 milliseconds
99.99% <= 5 milliseconds
100.00% <= 6 milliseconds
100.00% <= 6 milliseconds
9734.25 requests per second

====== LRANGE_600 (first 600 elements) ======
  100000 requests completed in 13.01 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

0.72% <= 1 milliseconds
98.59% <= 2 milliseconds
99.76% <= 3 milliseconds
99.94% <= 4 milliseconds
99.98% <= 5 milliseconds
100.00% <= 6 milliseconds
7689.35 requests per second

====== MSET (10 keys) ======
  100000 requests completed in 1.69 seconds
  20 parallel clients
  3 bytes payload
  keep alive: 1

99.98% <= 1 milliseconds
100.00% <= 1 milliseconds
59241.71 requests per second

可以看到執行了多個命令進行測試,如果只是希望測試部分命令的性能情況,可以參考下面的部分測試案例。

部分測試案例

[uplooking@uplooking01 ~]$ redis-benchmark -h uplooking01 -p 6379 -t set,lpush -n 100000 -q
SET: 75301.21 requests per second
LPUSH: 77101.00 requests per second

通過上面的測試,我們就可以知道我們的Redis環境的讀寫能力究竟如何。

Redis數據持久化

RDB(默認)

rdb方式的持久化是通過快照完成的,當符合一定條件時redis會自動將內存中的所有數據執行快照操作並存儲到硬盤上。
默認存儲在dump.rdb文件中。(文件名在配置文件中dbfilename)
redis進行快照的時機(在配置文件redis.conf中)
save 900 1:表示900秒內至少一個鍵被更改則進行快照。
save 300 10
save 60 10000
(redis自動實現快照的過程,見下面的文檔內容)

手動執行save或者bgsave命令讓redis執行快照。
兩個命令的區別在於,save是由主進程進行快照操作,會阻塞其它請求。bgsave是由redis執行fork函數復制出一個子進程來進行快照操作。
文件修復:redis-check-dump

rdb的優缺點
優點:由於存儲的有數據快照文件,恢復數據很方便。
缺點:會丟失最後一次快照以後更改的所有數據。

redis實現快照的過程:

1:redis使用fork函數復制一份當前進程的副本(子進程)
2:父進程繼續接收並處理客戶端發來的命令,而子進程開始將內存中的數據寫入硬盤中的臨時文件
3:當子進程寫入完所有數據後會用該臨時文件替換舊的RDB文件,至此,一次快照操作完成。

註意:redis在進行快照的過程中不會修改RDB文件,只有快照結束後才會將舊的文件替換成新的,也就是說任何時候RDB文件都是完整的。
這就使得我們可以通過定時備份RDB文件來實現redis數據庫的備份
RDB文件是經過壓縮的二進制文件,占用的空間會小於內存中的數據,更加利於傳輸。

AOF

AOF基本配置
aof方式的持久化是通過日誌文件的方式。默認情況下redis沒有開啟aof,可以通過參數appendonly參數開啟。
    appendonly yes

aof文件的保存位置和rdb文件的位置相同,都是dir參數設置的,默認的文件名是appendonly.aof,可以通過         appendfilename參數修改
    appendfilename appendonly.aof

redis寫命令同步的時機:

#appendfsync always 每次都會執行
appendfsync everysec 默認 每秒執行一次同步操作(推薦,默認)
#appendfsync no不主動進行同步,由操作系統來做,30秒一次

另外查看aof日誌文件,它的內容如下:

[uplooking@uplooking01 redis]$ tail -f appendonly.aof
single
$2
no
*3
$3
SET
$3
age
$2
18

其相關符號的說明如下:

*<參數數量>
$<參數 1 的字節數量> 
<參數 1 的數據> 
...
$<參數 N 的字節數量> 
<參數 N 的數據> 
aof日誌文件重寫
  auto-aof-rewrite-percentage 100(當目前aof文件大小超過上一次重寫時的aof文件大小的百分之多少時會再次進行重寫,如果之前沒有重寫,則以啟動時的aof文件大小為依據)
  auto-aof-rewrite-min-size 64mb
  手動執行bgrewriteaof進行重寫
  重寫的過程只和內存中的數據有關,和之前的aof文件無關。
  所謂的“重寫”其實是一個有歧義的詞語, 實際上, 
  AOF 重寫並不需要對原有的 AOF 文件進行任何寫入和讀取, 它針對的是數據庫中鍵的當前值。

文件修復:redis-check-aof

對於aof日誌文件重寫的概念再進一步說明:

所謂“重寫”其實是一個有歧義的詞語,實際上,AOF重寫並不需要對原有AOF文件進行任何寫入和讀取,
它針對的是數據庫中鍵的當前值。

假設服務器對鍵list執行了以下四條命令:
127.0.0.1:6379[1]> RPUSH list 1 2 3 4    //[1,2,3,4]
127.0.0.1:6379[1]> RPOP list                    //[1,2,3]
127.0.0.1:6379[1]> LPOP list            //[2,3]
當前列表鍵list在數據庫中的值就為[2,3]。要保存這個列表的當前狀態,並且盡量減少使用的命令數,
最簡單的方式不是去AOF文件分析前面執行的三條命令,而是直接讀取list鍵在數據庫中的當前值,
然後用一條RPUSH 2,3代替前面的三條命令。

根據鍵的類型,使用適當的寫入命令來重現鍵的當前值,這就是AOF重寫的實現原理
rdb切換到aof
動態切換redis持久方式,從RDB切換到AOF(支持Redis 2.2及以上)
  CONFIG SET appendonly yes
  CONFIG SET save ""(可選)

註意:當redis啟動時,如果rdb持久化和aof持久化都打開了,那麽程序會使用aof方式來恢復數據集,
因為aof方式所保存的數據通常是最完整的。如果aof文件丟失了,則啟動之後數據庫內容為空。

註意:如果想把正在運行的redis數據庫,從RDB切換到AOF,建議先使用動態切換方式,再修改配置文件,重啟數據庫。
(不能自己修改配置文件,重啟數據庫,否則數據庫中數據就為空了。因為此時會直接讀取aof文件的數據,
rdb的數據文件還存在,但是redis只會加載aof日誌文件。)

在實際測試時,效果跟上面的描述是一樣的:

1.先使用rdb的方式作為數據的持久化方式
2.向redis中添加數據
3.動態執行CONFIG SET appendonly yes
然後會發現在redis目錄下動態生成一個aof文件,並且其數據就是當前redis內存中的數據。

並且通過測試發現,假如age這個key是原來rdb中存在的數據,一旦動態切換,原來rdb的數據都會備份到aof日誌文件中,
這樣也就驗證了,其實動態切換的過程,會把當前redis內存中的數據都保存到aof日誌文件中。

Redis優化

Redis內存占用情況

 100萬個鍵值對(鍵是0到999999值是字符串“hello world”)在32位操作系統的筆記本上用了100MB
使用64位的操作系統的話,相對來說占用的內存會多一點,這是因為64位的系統裏指針占用了8個字節,
但是64位系統也能支持更大的內存,所以運行大型的redis服務還是建議使用64位服務器

一個Redis實例最多能存放多少keys
   理論上Redis可以處理多達232-1的keys,並且在實際中進行了測試,每個實例至少存放了2億5千萬的keys
   也可以說Redis的存儲極限是系統中的可用內存值。

Redis優化1:基本優化

1.精簡鍵名和鍵值
  鍵名:盡量精簡,但是也不能單純為了節約空間而使用不易理解的鍵名。
  鍵值:對於鍵值的數量固定的話可以使用0和1這樣的數字來表示,(例如:male/female、right/wrong)

2.當業務場景不需要數據持久化時,關閉所有的持久化方式可以獲得最佳的性能

3.內部編碼優化(了解)
    redis為每種數據類型都提供了兩種內部編碼方式,在不同的情況下redis會自動調整合適的編碼方式。(如圖所示)

4.SLOWLOG [get/reset/len]
  slowlog-log-slower-than 它決定要對執行時間大於多少微秒(microsecond,1秒 = 1,000,000 微秒)的命令進行記錄
  slowlog-max-len 它決定 slowlog 最多能保存多少條日誌
  當發現redis性能下降的時候可以查看下是哪些命令導致的

Redis優化2:內存使用優化

1.限制redis的內存大小
  通過redis的info命令查看內存使用情況
  如果不設置maxmemory或者設置為0,64位系統不限制內存,32位系統最多使用3GB內存。
  修改配置文件中的maxmemory和maxmemory-policy
  maxmemory:最大內存
  maxmemory-policy:內存不足時,數據清除策略

1.如果可以確定數據總量不大,並且內存足夠的情況下不需要限制redis使用的內存大小。
  如果數據量不可預估,並且內存也有限的話,盡量限制下redis使用的內存大小,這樣可以避免redis使用swap分區。

註意:如果不限制內存,當物理內存使用完之後,會使用swap分區,這樣性能較低,如果限制了內存,
     當到達指定內存之後就不能添加數據了,否則會報OOM錯誤。
     可以設置maxmemory-policy,內存不足時刪除數據。

更詳細的說明如下:

在硬盤上進行讀寫操作要比在內存上進行讀寫操作,時間上慢了近5個數量級,內存是0.1μs(微秒)、而硬盤是10ms(毫秒)。如果Redis進程上發生內存交換,那麽Redis和依賴Redis上數據的應用會受到嚴重的性能影響。 通過查看used_memory指標可知道Redis正在使用的內存情況,如果used_memory>可用最大內存,那就說明Redis實例正在進行內存交換或者已經內存交換完畢。管理員根據這個情況,執行相對應的應急措施。

排查方案:若是在使用Redis期間沒有開啟rdb快照或aof持久化策略,那麽緩存數據在Redis崩潰時就有丟失的危險。因為當Redis內存使用率超過可用內存的95%時,部分數據開始在內存與swap空間來回交換,這時就可能有丟失數據的危險。當開啟並觸發快照功能時,Redis會fork一個子進程把當前內存中的數據完全復制一份寫入到硬盤上。因此若是當前使用內存超過可用內存的45%時觸發快照功能,那麽此時進行的內存交換會變的非常危險(可能會丟失數據)。 倘若在這個時候實例上有大量頻繁的更新操作,問題會變得更加嚴重。

通過減少Redis的內存占用率,來避免這樣的問題,或者使用下面的技巧來避免內存交換發生:1:盡可能的使用Hash數據結構。因為Redis在儲存小於100個字段的Hash結構上,其存儲效率是非常高的。所以在不需要集合(set)操作或list的push/pop操作的時候,盡可能的使用Hash結構。比如,在一個web應用程序中,需要存儲一個對象表示用戶信息,使用單個key表示一個用戶,其每個屬性存儲在Hash的字段裏,這樣要比給每個屬性單獨設置一個key-value要高效的多。 通常情況下倘若有數據使用string結構,用多個key存儲時,那麽應該轉換成單key多字段的Hash結構。 如上述例子中介紹的Hash結構應包含,單個對象的屬性或者單個用戶各種各樣的資料。Hash結構的操作命令是HSET(key, fields, value)和HGET(key, field),使用它可以存儲或從Hash中取出指定的字段。

2:設置key的過期時間。一個減少內存使用率的簡單方法就是,每當存儲對象時確保設置key的過期時間。倘若key在明確的時間周期內使用或者舊key不大可能被使用時,就可以用Redis過期時間命令(expire,expireat, pexpire, pexpireat)去設置過期時間,這樣Redis會在key過期時自動刪除key。 假如你知道每秒鐘有多少個新key-value被創建,那可以調整key的存活時間,並指定閥值去限制Redis使用的最大內存。

3:回收key。在Redis配置文件中(一般叫Redis.conf),通過設置“maxmemory”屬性的值可以限制Redis最大使用的內存,修改後重啟實例生效。也可以使用客戶端命令config set maxmemory 去修改值,這個命令是立即生效的,但會在重啟後會失效,需要使用config rewrite命令去刷新配置文件。 若是啟用了Redis快照功能,應該設置“maxmemory”值為系統可使用內存的45%,因為快照時需要一倍的內存來復制整個數據集,也就是說如果當前已使用45%,在快照期間會變成95%(45%+45%+5%),其中5%是預留給其他的開銷。 如果沒開啟快照功能,maxmemory最高能設置為系統可用內存的95%。

當內存使用達到設置的最大閥值時,需要選擇一種key的回收策略,可在Redis.conf配置文件中修改“maxmemory-policy”屬性值。 若是Redis數據集中的key都設置了過期時間,那麽“volatile-ttl”策略是比較好的選擇。但如果key在達到最大內存限制時沒能夠迅速過期,或者根本沒有設置過期時間。那麽設置為“allkeys-lru”值比較合適,它允許Redis從整個數據集中挑選最近最少使用的key進行刪除(LRU淘汰算法)。Redis還提供了一些其他淘汰策略,如下:volatile-lru:使用LRU算法從已設置過期時間的數據集合中淘汰數據。volatile-ttl:從已設置過期時間的數據集合中挑選即將過期的數據淘汰。volatile-random:從已設置過期時間的數據集合中隨機挑選數據淘汰。allkeys-lru:使用LRU算法從所有數據集合中淘汰數據。allkeys-random:從數據集合中任意選擇數據淘汰no-enviction:禁止淘汰數據。

通過設置maxmemory為系統可用內存的45%或95%(取決於持久化策略)和設置“maxmemory-policy”為“volatile-ttl”或“allkeys-lru”(取決於過期設置),可以比較準確的限制Redis最大內存使用率,在絕大多數場景下使用這2種方式可確保Redis不會進行內存交換。倘若你擔心由於限制了內存使用率導致丟失數據的話,可以設置noneviction值禁止淘汰數據。

Redis優化3

Redis是個單線程模型,客戶端過來的命令是按照順序執行的,所以想要一次添加多條數據的時候可以使用管道(可以理解為批處理),或者使用一次可以添加多條數據的命令,例如:

set mset
get mget
lindex lrange
hset hmset
hget hmget

Redis筆記整理(三):進階操作與高級部分