Redis4.0 新特性嚐鮮

運維部落2018-05-14 06:39:53

1.目錄結構

  1. 目錄

  2. 前言

  3. 環境搭建


    1. 下載

    2. 安裝

    3. 集羣搭建

  4. 特性嚐鮮


    1. 注意事項

    2. 升級內容

    3. 模塊系統

    4. PSYNC 2.0

    5. 優化

    6. 非阻塞 DEL 、 FLUSHDB 和 FLUSHALL

    7. 交換數據庫

    8. 混合RDBAOF

    9. 內存命令

    10. 兼容 NAT 和 Docker

  5. 引用

2. 前言

2017-07-14 redis 4.0 Stable version release,新增了許多新功能,此次專門抽出時間,探索一些功能,把握Redis未來的發展方向,同時積累經驗,為未來升級Redis打下堅實基礎。學習新的東西,如果不將它記錄下來,過上兩週,基本上就忘記做過什麼了,對知識的掌握不利,以後儘量所有的學習都能產生文字記錄,便於自己總結學習各種技術,也能給新人帶去一點便利。

3. 環境搭建

安裝方式,較之前沒有多大變化,還是寫一下,便於新手學習。

3.1. 下載

1

2

$ wget http://download.redis.io/releases/redis-4.0.0.tar.gz

$ tar xzf redis-4.0.0.tar.gz

3.2. 編譯安裝

1

2

$ cd redis-4.0.0

$ make

如果需要將redis-cli,redis-server等相關命令安裝到/bin目錄下,全局的話,可以使用如下命令:

1

$ make install


或者利用軟連接實現:

1

2

3

$ make

$ ln -s redis-4.0.0/src/redis-server /bin/redis-server

$ ln -s redis-4.0.0/src/redis-cli /bin/redis-cli

在編譯中可能會遇到如下問題:

1

zmalloc.h:50:31: 錯誤:jemalloc/jemalloc.h:沒有那個文件或目錄


出現這個問題是libc 並不是默認的 分配器, 默認的是 jemalloc, 因為 jemalloc 被證明 有更少的 fragmentation problems 比libc,關於更詳細信息可以查看redis中REAME,md,其中有詳細介紹,此處不再細説。

解決辦法:

1

make MALLOC=libc


3.3. 新建集羣

按照官方指導,搭建3m+3s集羣,端口號7000-7005

以下為創建腳本:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

#!/bin/bash

nodes=(7000 7001 7002 7003 7004 7005)

HOME_DIR=`pwd`

function create(){

echo "create"

if [ -d redis_cluster ];then

rm -rf redis_cluster

fi

mkdir redis_cluster

cd redis_cluster

mkdir `echo ${nodes[*]}`

for var in ${nodes[*]}

do

cd $var

touch $var-redis.conf

echo "port" $var >> $var-redis.conf

echo "cluster-enabled yes" >> $var-redis.conf

echo "cluster-config-file nodes.conf" >> $var-redis.conf

echo "cluster-node-timeout 5000" >> $var-redis.conf

echo "appendonly yes" >> $var-redis.conf

echo "daemonize yes" >> $var-redis.conf

echo "pidfile redis.pid" >> $var-redis.conf

cd ../

done

run;

src/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

}

function run(){

echo run

for var in ${nodes[*]}

do

cd $HOME_DIR/redis_cluster/$var/

redis-server $var-redis.conf

cd $HOME_DIR/

echo Start redis ports ${var} finish.

done

}

function stop(){

cd $HOME_DIR/redis_cluster/

DIRS=`ls -l | grep "^d" | awk '{print $NF}'`

for d in $DIRS

do

PID=`cat $d/redis.pid`

if [ -n "$PID" ];then

kill -9 $PID

rm -f $d/redis.pid

fi

done

cd $HOME_DIR/

echo Stop redis ports ${DIRS} finish.

}

case $1 in

create)

echo " create redis cluster 錛?000,7001,7002,7003,7004.7005,7006,7007"

create

;;

run)

run

;;

stop)

stop

;;

*)

echo "Usage:[create|run|stop]"

;;

esac

執行

1

sh createCluster.sh create

一路回車即可,注意構建集羣需要使用redis-trib.rb,需要額外執行

1

gem install redis

結果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

[[email protected] redis-4.0.0]$ redis-cli -c -h 127.0.0.1 -p 7000

127.0.0.1:7000> cluster nodes

63e698210378f4fda23c4070bea3b46f93952811 127.0.0.1:[email protected] myself,master - 0 1500391716000 1 connected 0-5460

4091630217b64ece9a6fa55c26687a10c1f9a8b5 127.0.0.1:[email protected] master - 0 1500391717501 2 connected 5461-10922

0b23853c3aa4f5b942a6239bc7bca71df36e121c 127.0.0.1:[email protected] slave 12d05fb7c20bf001759f80cf3f65ad9df4b01af5 0 1500391716498 6 connected

12d05fb7c20bf001759f80cf3f65ad9df4b01af5 127.0.0.1:[email protected] master - 0 1500391717000 3 connected 10923-16383

2e559b462362a9563f98b398af3984c05e25ef19 127.0.0.1:[email protected] slave 63e698210378f4fda23c4070bea3b46f93952811 0 1500391716000 4 connected

c4f8e0a95579c772c7506c195b3c7984c73312b4 127.0.0.1:[email protected] slave 4091630217b64ece9a6fa55c26687a10c1f9a8b5 0 1500391716000 5 connected

127.0.0.1:7000> set a a

-> Redirected to slot [15495] located at 127.0.0.1:7002

OK

127.0.0.1:7002> get a

"a"

127.0.0.1:7002>

4. 特性嚐鮮

4.1 注意事項

IMPORTANT: Redis Cluster users, please note that, as specified in the list

of incompatibilities, Redis 4.0 cluster bus protocol is not compatible with

Redis 3.2, so in order to upgrade, a mass reboot of the instances is needed

and rolling upgrades are not possible. This change was needed in order to

add compatibility for Containers/NAT, where the bus port at a fixed offset

was not an acceptable design, so we had to change many things, resulting

in the incompatible protocol.


4.0版本與3.2版本傳輸協議不兼容,更改該協議的目的是為了實現Containers/NAT

為了升級,需要重啟大量節點,無法做到滾動升級。

4.2 升級內容

  • Different replication fixes to PSYNC2, the new 4.0 replication engine.

  • Modules thread safe contexts were introduced. They are an >experimental API right now, but the API is considered to be stable and usable when needed.

  • SLOWLOG now logs the offending client name and address. Note that this is a backward compatibility breakage in case old code assumes that the slowlog entry is composed of exactly three entries.

  • The modules native data types RDB format changed.

  • The AOF check utility is now able to deal with RDB preambles.

  • GEORADIUS_RO and GEORADIUSBYMEMBER_RO variants, not supporting the STORE option, were added in order to allow read-only scaling of such queries.

  • HSET is now variadic, and HMSET is considered deprecated (but will be supported for years to come). Please use HSET in new code.

  • GEORADIUS huge radius (>= ~6000 km) corner cases fixed, certain elements near the edges were not returned.

  • DEBUG DIGEST modules API added.

  • HyperLogLog commands no longer crash on certain input (non HLL) strings.

  • Fixed SLAVEOF inside MULTI/EXEC blocks.

  • Many other minor bug fixes and improvements.

4.3 模塊系統

Redis 4.0 發生的最大變化就是加入了模塊系統, 這個系統可以讓用户通過自己編寫的代碼來擴展和實現 Redis 本身並不具備的功能, 具體使用方法可以參考 antirez 的博文《Redis Loadable Module System》: http://antirez.com/news/106

因為模塊系統是通過高層次 API 實現的, 它與 Redis 內核本身完全分離、互不干擾, 所以用户可以在有需要的情況下才啟用這個功能, 以下是 redis.conf 中記載的模塊載入方法:

1

2

3

4

5

6

7

################################## MODULES #####################################

# Load modules at startup. If the server is not able to load modules

# it will abort. It is possible to use multiple loadmodule directives.

#

# loadmodule /path/to/my_module.so

# loadmodule /path/to/other_module.so


目前已經有人使用這個功能開發了各種各樣的模塊, 比如 Redis Labs 開發的一些模塊就可以在 http://redismodules.com 看到, 此外 antirez 自己也使用這個功能開發了一個神經網絡模塊: https://github.com/antirez/neural-redis

模塊功能使得用户可以將 Redis 用作基礎設施, 並在上面構建更多功能, 這給 Redis 帶來了無數新的可能性。

4.4 PSYNC 2.0

新版本的 PSYNC 命令解決了舊版本的 Redis 在複製時的一些不夠優化的地方:

  • 在舊版本 Redis 中, 如果一個從服務器在 FAILOVER 之後成為了新的主節點, 那麼其他從節點在複製這個新主的時候就必須進行全量複製。 在 Redis 4.0 中, 新主和從服務器在處理這種情況時, 將在條件允許的情況下使用部分複製。

  • 在舊版本 Redis 中, 一個從服務器如果重啟了, 那麼它就必須與主服務器重新進行全量複製, 在 Redis 4.0 中, 只要條件允許, 主從在處理這種情況時將使用部分複製。

4.5 緩存驅逐策略優化

新添加了 Last Frequently Used 緩存驅逐策略, 具體信息見 antirez 的博文《Random notes on improving the Redis LRU algorithm》: http://antirez.com/news/109

另外 Redis 4.0 還對已有的緩存驅逐策略進行了優化, 使得它們能夠更健壯、高效、快速和精確。

4.6 非阻塞 DEL 、 FLUSHDB 和 FLUSHALL

在 Redis 4.0 之前, 用户在使用 DEL 命令刪除體積較大的鍵, 又或者在使用 FLUSHDB 和 FLUSHALL 刪除包含大量鍵的數據庫時, 都可能會造成服務器阻塞。

為了解決以上問題, Redis 4.0 新添加了 UNLINK 命令, 這個命令是 DEL 命令的異步版本, 它可以將刪除指定鍵的操作放在後台線程裏面執行, 從而儘可能地避免服務器阻塞:

1

2

3

4

5

6

7

8

9

127.0.0.1:7002> set a test

OK

127.0.0.1:7002> get a

"test"

127.0.0.1:7002> unlink a

(integer) 1

127.0.0.1:7002> get a

(nil)


因為一些歷史原因, 執行同步刪除操作的 DEL 命令將會繼續保留。

此外, Redis 4.0 中的 FLUSHDB 和 FLUSHALL 這兩個命令都新添加了 ASYNC 選項, 帶有這個選項的數據庫刪除操作將在後台線程進行:

1

2

3

4

5

redis> FLUSHDB ASYNC

OK

redis> FLUSHALL ASYNC

OK


4.7 交換數據庫

Redis 4.0 對數據庫命令的另外一個修改是新增了 SWAPDB 命令, 這個命令可以對指定的兩個數據庫進行互換: 比如説, 通過執行命令 SWAPDB 0 1 , 我們可以將原來的數據庫 0 變成數據庫 1 , 而原來的數據庫 1 則變成數據庫 0 。這種場景是在非集羣模式下使用的,在集羣模式是不支持切換數據庫的。默認所有的節點使用index 0。

以下是一個使用 SWAPDB 的例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

redis> SET your_name "aibibang" -- 在數據庫 0 中設置一個鍵

OK

redis> GET your_name

"aibibang"

redis> SWAPDB 0 1 -- 互換數據庫 0 和數據庫 1

OK

redis> GET your_name -- 現在的數據庫 0 已經沒有之前設置的鍵了

(nil)

redis> SELECT 1 -- 切換到數據庫 1

OK

redis[1]> GET your_name -- 之前在數據庫 0 設置的鍵現在可以在數據庫 1 找到

"aibibang" -- 證明兩個數據庫已經互換


4.8 混合 RDB-AOF 持久化格式

Redis 4.0 新增了 RDB-AOF 混合持久化格式, 這是一個可選的功能, 在開啟了這個功能之後, AOF 重寫產生的文件將同時包含 RDB 格式的內容和 AOF 格式的內容, 其中 RDB 格式的內容用於記錄已有的數據, 而 AOF 格式的內存則用於記錄最近發生了變化的數據, 這樣 Redis 就可以同時兼有 RDB 持久化和 AOF 持久化的優點 —— 既能夠快速地生成重寫文件, 也能夠在出現問題時, 快速地載入數據。

這個功能可以通過 aof-use-rdb-preamble 選項進行開啟, redis.conf 文件中記錄了這個選項的使用方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

When rewriting the AOF file, Redis is able to use an RDB preamble in the

# AOF file for faster rewrites and recoveries. When this option is turned

# on the rewritten AOF file is composed of two different stanzas:

#

# [RDB file][AOF tail]

#

# When loading Redis recognizes that the AOF file starts with the "REDIS"

# string and loads the prefixed RDB file, and continues loading the AOF

# tail.

#

# This is currently turned off by default in order to avoid the surprise

# of a format change, but will at some point be used as the default.

aof-use-rdb-preamble no


4.9 內存命令

新添加了一個 MEMORY 命令, 這個命令可以用於視察內存使用情況, 並進行相應的內存管理操作:

1

2

3

4

5

127.0.0.1:7002> memory help

1) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key"

2) "MEMORY STATS - Show memory usage details"

3) "MEMORY PURGE - Ask the allocator to release memory"

4) "MEMORY MALLOC-STATS - Show allocator internal stats"


其中, 使用 MEMORY USAGE 估算儲存給定鍵所需的內存:

1

2

3

4

5

6

127.0.0.1:7002> set truman aibibang

-> Redirected to slot [2113] located at 127.0.0.1:7000

OK

127.0.0.1:7000> memory usage truman

(integer) 59


使用 MEMORY STATS 子命令可以查看 Redis 當前的內存使用情況:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

127.0.0.1:7000> memory stats

1) "peak.allocated"

2) (integer) 2228415

3) "total.allocated"

4) (integer) 2228474

5) "startup.allocated"

6) (integer) 1054396

7) "replication.backlog"

8) (integer) 1048584

9) "clients.slaves"

10) (integer) 16858

11) "clients.normal"

12) (integer) 49630

13) "aof.buffer"

14) (integer) 0

15) "db.0"

16) 1) "overhead.hashtable.main"

2) (integer) 112

3) "overhead.hashtable.expires"

4) (integer) 0

17) "overhead.total"

18) (integer) 2169580

19) "keys.count"

20) (integer) 2

21) "keys.bytes-per-key"

22) (integer) 587039

23) "dataset.bytes"

24) (integer) 58894

25) "dataset.percentage"

26) "5.0161914825439453"

27) "peak.percentage"

28) "100.00264739990234"

29) "fragmentation"

30) "1.2773568630218506"


使用 MEMORY PURGE 子命令可以要求分配器釋放更多內存:

1

2

redis> MEMORY PURGE

OK


使用 MEMORY MALLOC-STATS 子命令可以展示分配器內部狀態:

1

2

redis> MEMORY MALLOC-STATS

Stats not supported for the current allocator


4.10 兼容NAT和Docker

Redis 4.0 將兼容 NAT 和 Docker , 具體的使用方法在 redis.conf 中有記載:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

########################## CLUSTER DOCKER/NAT support ########################

# In certain deployments, Redis Cluster nodes address discovery fails, because

# addresses are NAT-ted or because ports are forwarded (the typical case is

# Docker and other containers).

#

# In order to make Redis Cluster working in such environments, a static

# configuration where each node known its public address is needed. The

# following two options are used for this scope, and are:

#

# * cluster-announce-ip

# * cluster-announce-port

# * cluster-announce-bus-port

#

# Each instruct the node about its address, client port, and cluster message

# bus port. The information is then published in the header of the bus packets

# so that other nodes will be able to correctly map the address of the node

# publishing the information.

#

# If the above options are not used, the normal Redis Cluster auto-detection

# will be used instead.

#

# Note that when remapped, the bus port may not be at the fixed offset of

# clients port + 10000, so you can specify any port and bus-port depending

# on how they get remapped. If the bus-port is not set, a fixed offset of

# 10000 will be used as usually.

#

# Example:

#

# cluster-announce-ip 10.1.1.5

# cluster-announce-port 6379

# cluster-announce-bus-port 6380

5. 引用

  1. Redis 4.0新功能介紹

  2. Redis 4.0 release note


閲讀原文

TAGS: