Redis提供了兩種Persistence策略,RDB和AOF。RDB是預設的,它定時建立資料庫的完整磁碟映象,即dump.rdb檔案。建立映象的時間間隔是可以設定的,假如每5分鐘建立一次映象,那麼當系統崩潰時使用者可能會丟失5分鐘的資料。因此,RDB不是一個可靠性很高的方案,但是效能不錯。RDB非常容易備份,使用者直接將dump.rdb檔案複製即可。為了提供更好的可靠性,Redis支援AOF,即將操作寫入日誌中(appendonly.aof檔案)。寫日誌的策略可以是每秒一次或每次操作一次,顯然每秒一次意味著使用者可能丟失1秒的資料,而每次操作一次的可靠性最高,但是效能最差。日誌檔案可能會增長到非常大,因此Redis後臺會執行rewrite操作整理日誌。AOF不適合備份。
Redis推薦使用RDB,以及在需要可靠性的時候用RDB+AOF,不推薦單獨使用AOF。Redis為了減少磁碟的負載,任何時刻都不會同時執行寫映象和寫日誌。更多RDB和AOF的細節可以參見官網。本文會測試寫負載比較重時,RDB和RDB+AOF的效能。
Redis還提供主從同步的功能,可以為Redis配置一臺slave,當master崩潰時,slave可以接管master的工作。這其中就涉及到主從同步的操作,即replication。Redis採用非同步replication。本文會測試寫負載很高時,replication對效能的影響。
1. 實驗環境
因為persistence和replication與寫負載關係很大,所以選擇了read/update各佔50%的workloada。使用的兩臺服務在同一百兆乙太網內,16GB記憶體,一個執行YCSB,一個執行redis-server。測試時,首先向Redis插入100萬條記錄,然後再執行100萬條操作(read和update各50%),統計延遲。測試replication時需要第三臺伺服器,也是16GB記憶體。AOF每秒執行一次。
2. RDB與AOF
load階段的結果。
load階段 | RDB | AOF |
run time (ms) | 807436.0 | 864731.0 |
Avg. insert latency (ms) | 801.21 | 858.34 |
Min insert latency (ms) | 605 | 645 |
Max insert latency (ms) | 37397 | 5855846 |
95th percentile insert latency (ms) | 0 | 0 |
99th percentile insert latency (ms) | 0 | 0 |
run階段的結果。
run階段 | RDB | AOF |
run time (ms) | 401831.0 | 437653.0 |
Avg. update latency (ms) | 299.55 | 341.54 |
Min update latency (ms) | 157 | 174 |
Max update latency (ms) | 39069 | 7333105 |
95th percentile update latency (ms) | 0 | 0 |
99th percentile update latency (ms) | 0 | 0 |
Avg. read latency (ms) | 489.56 | 519.13 |
Min read latency (ms) | 342 | 359 |
Max read latency (ms) | 42185 | 7278363 |
95th percentile read latency (ms) | 0 | 0 |
99th percentile read latency (ms) | 0 | 0 |
可見AOF對平均延遲有7%-14%的影響,而對最大延遲的影響非常大,可能的原因是在執行AOF的rewrite時延遲很大(純屬猜測)。
3. replication
此實驗關閉AOF,實驗前,同時開啟主從伺服器。
load階段的結果。
load階段 | non-replication | replication |
run time (ms) | 807436.0 | 786098.0 |
Avg. insert latency (ms) | 801.21 | 780.44 |
Min insert latency (ms) | 605 | 496 |
Max insert latency (ms) | 37397 | 61072 |
95th percentile insert latency (ms) | 0 | 0 |
99th percentile insert latency (ms) | 0 | 0 |
run階段的結果。
run階段 | non-replication | replication |
run time (ms) | 401831.0 | 398683.0 |
Avg. update latency (ms) | 299.55 | 294.72 |
Min update latency (ms) | 157 | 164 |
Max update latency (ms) | 39069 | 37605 |
95th percentile update latency (ms) | 0 | 0 |
99th percentile update latency (ms) | 0 | 0 |
Avg. read latency (ms) | 489.56 | 488.82 |
Min read latency (ms) | 342 | 318 |
Max read latency (ms) | 42185 | 201731 |
95th percentile read latency (ms) | 0 | 0 |
99th percentile read latency (ms) | 0 | 0 |
可見replication對效能影響不大。為了進一步觀察,我在load階段結束之後,同時執行空的slave和負載。
run階段 | replication |
run time (ms) | 490977.0 |
Avg. update latency (ms) | 390.52 |
Min update latency (ms) | 171 |
Max update latency (ms) | 153180 |
95th percentile update latency (ms) | 0 |
99th percentile update latency (ms) | 5 |
Avg. read latency (ms) | 577.92 |
Min read latency (ms) | 304 |
Max read latency (ms) | 201658 |
95th percentile read latency (ms) | 0 |
99th percentile read latency (ms) | 5 |
這次實驗在執行負載時,要進行大量replication,可以看到執行時間增加了25%,而且最大延遲和99th percentile延遲也增加明顯。