Redis雜記

一、Redis基礎

1、安裝啓動Redis

1.1 去pkgs.org下載rpm包

[root@node1 ~]# wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/redis-3.0.7-4.el6.art.i686.rpm

1.2 yum本地安裝

[root@node1 ~]# yum localinstall redis-3.0.7-4.el6.art.i686.rpm

查看redis安裝生成的文件:
[root@node1 ~]# rpm -ql redis

備份原始配置:
[root@node1 ~]# cp -p /etc/redis.conf{,.orgi}

1.3 配置

[root@node1 ~]# vim /etc/redis.conf

#監聽多個地址:
bind 127.0.0.1 10.201.106.21

啓動:
[root@node1 ~]# service redis start
Starting redis-server:                                     [  OK  ]
[root@node1 ~]# ss -tnlp | grep redis
LISTEN     0      128           10.201.106.21:6379                     *:*      users:(("redis-server",16155,5))
LISTEN     0      128               127.0.0.1:6379                     *:*      users:(("redis-server",16155,4))

2、Redis使用

2.1 連接

[root@node1 ~]# redis-cli
127.0.0.1:6379> 

獲取幫助:
127.0.0.1:6379> help

查看支持的字符:
127.0.0.1:6379> help @STRING

查看單個命令用法:
127.0.0.1:6379> HELP APPEND

  APPEND key value
  summary: Append a value to a key
  since: 2.0.0
  group: string

TAB鍵可以補全命令
127.0.0.1:6379> HELP 按tab

命令是分組的:
127.0.0.1:6379> help @server
列出連接的客戶端:
127.0.0.1:6379> CLIENT LIST

2.1.1 雜項

打開1號數據庫:
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> 

默認是0號數據庫:
127.0.0.1:6379[4]> SELECT 0
OK
127.0.0.1:6379> 

2.2 數據類型常用命令

2.2.1 String

查看幫助:
127.0.0.1:6379> help @string

設置disto字串的值爲fedora
127.0.0.1:6379> SET disto fedora
OK

獲取disto的值
127.0.0.1:6379> GET disto
"fedora"

在同一個名稱空間,對同一個鍵的二次定義,是修改其值:
127.0.0.1:6379> SET disto centos
OK
127.0.0.1:6379> GET disto
"centos"

附加延長字串:
127.0.0.1:6379> append disto slackware
(integer) 15
127.0.0.1:6379> GET disto
"centosslackware"

獲取字串長度:
127.0.0.1:6379> STRLEN disto
(integer) 15

NX:鍵不存在才設定
可以通過SETNX判斷鍵是否存在,不存在才創建,避免覆蓋之前的:
127.0.0.1:6379> SET disto gentoo NX
(nil)  #提示操作未能執行

還是原來的值
127.0.0.1:6379> GET disto
"centosslackware"

XX:鍵存在才設定:
127.0.0.1:6379> SET foo bar XX
(nil)

設置count鍵值爲0,通過INCR不斷加1
127.0.0.1:6379> SET count 0
OK
127.0.0.1:6379> INCR count
(integer) 1
127.0.0.1:6379> INCR count
(integer) 2
127.0.0.1:6379> INCR count
(integer) 3
127.0.0.1:6379> INCR count
(integer) 4
127.0.0.1:6379> GET count
"4"

減1:
127.0.0.1:6379> DECR count
(integer) 3
127.0.0.1:6379> DECR count
(integer) 2
127.0.0.1:6379> GET count
"2"
127.0.0.1:6379> DECR count
(integer) 1
127.0.0.1:6379> DECR count
(integer) 0
127.0.0.1:6379> DECR count
(integer) -1
127.0.0.1:6379> GET count
"-1"

無法遞增字符內容:
127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> incr foo
(error) ERR value is not an integer or out of range

2.2.2 List[字串容器]

查看幫助:
127.0.0.1:6379> help @list

定義一個列表:
127.0.0.1:6379> LPUSH list1 mon
(integer) 1

獲取第一個元素:
127.0.0.1:6379> lindex list1 0
"mon"

從左側賦值:
127.0.0.1:6379> LPUSH list1 sun
(integer) 2
127.0.0.1:6379> lindex list1 0
"sun"
127.0.0.1:6379> lindex list1 1
"mon"

從右側賦值:
127.0.0.1:6379> RPUSH list1 tue
(integer) 3
127.0.0.1:6379> LINDEX list1 2
"tue"

修改值:
127.0.0.1:6379> LSET list1 1 fri
OK
127.0.0.1:6379> LINDEX list1 1
"fri"

從右側彈出值(刪除):
127.0.0.1:6379> RPOP list1
"tue"
127.0.0.1:6379> RPOP list1
"fri"
127.0.0.1:6379> RPOP list1
"sun"
127.0.0.1:6379> RPOP list1
(nil)  #沒有值了,無法執行

2.2.3 Sets(集合)

查看集合命令幫助:
127.0.0.1:6379> HELP @SET

創建一個新的集合:
127.0.0.1:6379> SADD w1 mon tue wed thu fri sat sun
(integer) 7

創建第二個集合:
127.0.0.1:6379> SADD w2 tue thu day
(integer) 3

求兩個集的交集(列出兩個集合,同時擁有的值):
127.0.0.1:6379> SINTER w1 w2
1) "thu"
2) "tue"

求並集(大家都有的只留一份):
127.0.0.1:6379> SUNION w1 w2
1) "mon"
2) "tue"
3) "wed"
4) "fri"
5) "sat"
6) "sun"
7) "thu"
8) "day"

彈出元素(隨機,無法控制):
127.0.0.1:6379> SPOP w1
"fri"
127.0.0.1:6379> SPOP w1
"sun"

判斷元素是否在集合裏面
127.0.0.1:6379> SISMEMBER w1 mon
(integer) 1
127.0.0.1:6379> SISMEMBER w1 sun
(integer) 0     #0表示不是

2.2.4 Sorted Sets(有序集合)

score=內建索引號碼,內置排序號碼。跟普通位置索引是兩回事。但是score大小決定你的索引位置

查看幫助:
127.0.0.1:6379> help @sorted_set

定義有序集合:
127.0.0.1:6379> ZADD weekday1 1 mon 2 tue 3 wed
(integer) 3

查看集合的元素個數:
127.0.0.1:6379> ZCARD weekday1
(integer) 3

查看元素對應的索引號:
127.0.0.1:6379> ZRANK weekday1 tue
(integer) 1
127.0.0.1:6379> ZRANK weekday1 wed
(integer) 2

根據元素獲取score
127.0.0.1:6379> ZSCORE weekday1 wed
"3"

指定索引返回元素:
127.0.0.1:6379> ZRANGE weekday1 0 2
1) "mon"
2) "tue"
3) "wed"

127.0.0.1:6379> ZRANGE weekday1 0 1
1) "mon"
2) "tue"

2.2.5 Hashed(映射)

外鍵指向整個映射,內鍵指明指定字段的值

查看幫助:
127.0.0.1:6379> help @hash

定義鍵:
127.0.0.1:6379> HSET h1 a mon
(integer) 1

獲取指定映射內,指定字段的值:
127.0.0.1:6379> HGET h1 a
"mon"

在映射內添加新字段並賦值:
127.0.0.1:6379> HSET h1 b tue
(integer) 1
127.0.0.1:6379> HGET h1 b
"tue"

獲取映射裏面的所有鍵:
127.0.0.1:6379> HKEYS h1
1) "a"
2) "b"

獲取映射裏面的所有元素(鍵值)
127.0.0.1:6379> HVALS h1
1) "mon"
2) "tue"

獲取映射裏面的元素個數
127.0.0.1:6379> HLEN h1
(integer) 2

二、其它應用

1、Redis認證功能

1.1 編輯配置

設置密碼爲“redis123”
[root@node1 ~]# vim /etc/redis.conf

requirepass redis123

重啓服務:
[root@node1 ~]# service redis restart
Stopping redis-server:                                     [  OK  ]
Starting redis-server:                                     [  OK  ]

1.2 驗證

之前的默認連接方法:
[root@node1 ~]# redis-cli -h 10.201.106.21
10.201.106.21:6379> SELECT 0
(error) NOAUTH Authentication required.

認證:
10.201.106.21:6379> AUTH redis123
OK
10.201.106.21:6379> SELECT 0
OK

爲了後面實驗方便,將上面密碼配置註釋掉,重啓服務,取消認證

2、Redis管理

2.1 清空數據庫:

FLUSHDB:清空當前庫
FLUSHALL:清空所有庫

127.0.0.1:6379> FLUSHDB
OK

2.2 事務(通過MULTI,EXEC,WATCH等命令實現事務功能)

2.2.1 事務示例

啓動一個事務:
127.0.0.1:6379> MULTI
OK

#不會馬上執行,而是放在隊列中
127.0.0.1:6379> SET ip 192.168.1.1
QUEUED
127.0.0.1:6379> GET ip
QUEUED
127.0.0.1:6379> SET port 8080
QUEUED
127.0.0.1:6379> GET port
QUEUED

事務執行(結果一併返回):
127.0.0.1:6379> EXEC
1) OK
2) "192.168.1.1"
3) OK
4) "8080"

2.2.2 WATCH(樂觀鎖演示)

ip鍵啓動樂觀鎖監控
127.0.0.1:6379> WATCH ip
OK

開啓事務:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set IP 10.0.0.1
QUEUED
127.0.0.1:6379> GET ip
QUEUED

然後在EXEC之前,新開一個redis客戶端窗口修改ip鍵的值:
127.0.0.1:6379> SET ip 172.16.0.1
OK
127.0.0.1:6379> get ip
"172.16.0.1"

回到第一個開啓事務的窗口執行EXEC,由於ip值已經發生修改,事務執行失敗
127.0.0.1:6379> EXEC
(nil)       #事務未執行

2.2.3 一致性

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> GET ip
QUEUED
127.0.0.1:6379> SET port 6379
QUEUED
127.0.0.1:6379> SETT
(error) ERR unknown command 'SETT'
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.

2.3 Redis的連接

2.3.1 PING

測試服務器是否在線
127.0.0.1:6379> PING
PONG

2.3.2 ECHO

127.0.0.1:6379> ECHO "hello redis"
"hello redis"

2.3.3 查看連接相關命令幫助

127.0.0.1:6379> help @connection

2.4 服務器端常用命令

2.4.1 查看幫助

127.0.0.1:6379> help @server

2.4.2 獲取當前客戶端連接名

連接沒有指定,所以爲空
127.0.0.1:6379> CLIENT GETNAME
(nil)

2.4.3 關閉客戶端連接

127.0.0.1:6379> CLIENT KILL 127.0.0.1:49928
OK

2.4.4 設定當前連接名

127.0.0.1:6379> CLIENT SETNAME localconnect
OK
127.0.0.1:6379> CLIENT GETNAME
"localconnect"

2.4.5 獲取當前服務器狀態信息

127.0.0.1:6379> INFO

只顯示內存段信息:
127.0.0.1:6379> INFO Memory
# Memory
used_memory:657760
used_memory_human:642.34K
used_memory_rss:1716224
used_memory_peak:678504
used_memory_peak_human:662.60K
used_memory_lua:24576
mem_fragmentation_ratio:2.61
mem_allocator:jemalloc-3.6.0

重置info統計信息:
CONFIG RESETSTAT

2.4.6 修改配置

運行時修改指定參數,只保存在內存
CONFIG SET parameter value :

把在內存修改的新值同步到文件中
CONFIG REWRITE

2.4.7 查看鍵的數量

127.0.0.1:6379> DBSIZE
(integer) 2

2.4.8 獲取最新一次SAVE保存時間戳

127.0.0.1:6379> LASTSAVE
(integer) 1525450413

2.4.9 實時監控所接收的請求

127.0.0.1:6379> MONITOR
OK

2.4.10 把數據同步後,關閉服務

SHUTDOWN  [SAVE]

3、Redis的發佈訂閱

3.1 查看相關命令幫助

127.0.0.1:6379> HELP @pubsub

3.2 簡單示例

訂閱news頻道:
127.0.0.1:6379> SUBSCRIBE news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1

發佈消息:
127.0.0.1:6379> PUBLISH news "heloow world"
(integer) 1
127.0.0.1:6379> PUBLISH news abc
(integer) 1

自動接收消息:

Redis雜記

3.3 退訂頻道

UNSUBSCRIBE:退訂此前訂閱的頻道;

4、模式匹配

127.0.0.1:6379> PSUBSCRIBE "new.i[to]"
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "new.i[to]"
3) (integer) 1

127.0.0.1:6379> PUBLISH new.io redis
(integer) 1
127.0.0.1:6379> PUBLISH new.it qq
(integer) 1

Redis雜記

5、持久化

5.1 列出redis持久化備份目錄

127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"

5.2 RDB持久化相關配置

RDB相關配置
  stop-writes-on-bgsave-error yes
  rdbcompression yes
  rdbchecksum yes
  dbfilename dump.rdb
  dir /var/lib/redis/

關閉RDB:
save ""

5.3 AOF持久化

5.3.1 AOF配置

#默認關閉
appendonly no

appendfilename "appendonly.aof"
appendfsync {always|everysec|no}
no-appendfsync-on-rewrite no

#達到兩倍開始重寫AOF文件
auto-aof-rewrite-percentage 100
#AOF文件達到64M才重寫
auto-aof-rewrite-min-size 64mb

5.4 備份恢復優先使用AOF備份

6、Redis複製(主從)

6.1 從服務器配置(node2)

安裝redis:
[root@node2 ~]# yum -y localinstall redis-3.0.7-4.el6.art.i686.rpm

修改監聽端口:
bind 10.201.106.22 127.0.0.1

服務啓動:
[root@node2 ~]# service redis start
Starting redis-server:                                     [  OK  ]

服務器配置SLAVE:
[root@node2 ~]# redis-cli 
127.0.0.1:6379> SLAVEOF 10.201.106.21 6379
OK

現在node2已經是從服務器了

日誌查看:
[root@node2 ~]# tail -20 /var/log/redis/redis.log 
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

1694:M 14 Sep 04:35:05.444 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1694:M 14 Sep 04:35:05.444 # Server started, Redis version 3.0.7
1694:M 14 Sep 04:35:05.444 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1694:M 14 Sep 04:35:05.444 * The server is now ready to accept connections on port 6379
1694:S 14 Sep 04:36:03.912 * SLAVE OF 10.201.106.21:6379 enabled (user request from 'id=2 addr=127.0.0.1:54185 fd=6 name= age=32 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
1694:S 14 Sep 04:36:04.156 * Connecting to MASTER 10.201.106.21:6379
1694:S 14 Sep 04:36:04.156 * MASTER <-> SLAVE sync started
1694:S 14 Sep 04:36:04.157 * Non blocking connect for SYNC fired the event.
1694:S 14 Sep 04:36:04.159 * Master replied to PING, replication can continue...
1694:S 14 Sep 04:36:04.160 * Partial resynchronization not possible (no cached master)
1694:S 14 Sep 04:36:04.196 * Full resync from master: d76cae20eecf731fd10f73a5498e61197a60e9de:1
1694:S 14 Sep 04:36:04.256 * MASTER <-> SLAVE sync: receiving 44 bytes from master
1694:S 14 Sep 04:36:04.256 * MASTER <-> SLAVE sync: Flushing old data
1694:S 14 Sep 04:36:04.256 * MASTER <-> SLAVE sync: Loading DB in memory
1694:S 14 Sep 04:36:04.256 * MASTER <-> SLAVE sync: Finished with success

主服務器配置

Redis雜記

從服務器查看已經同步qq鍵值

Redis雜記

清除主配置:
127.0.0.1:6379> FLUSHALL
OK

從庫空了:
127.0.0.1:6379> KEYS *
(empty list or set)

獲取從庫配置:
127.0.0.1:6379> CONFIG GET slaveof
1) "slaveof"
2) "10.201.106.21 6379"

注意:如果master使用requirepass開啓了認證功能,從服務器要使用masterauth <PASSWORD> 來連入服務器請求此密碼進行認證

7、sentinel(哨兵,監測主從)

7.1 sentinel配置準備

關閉node2的redis進程
[root@node2 ~]# killall redis-server

在node2服務器啓動三個redis進程,一個主庫,兩個從庫(相當於一臺機器啓動三個redis)

創建配置存放目錄:
[root@node2 ~]# mkdir -pv /etc/redis

拷貝配置文件到目錄:
[root@node2 ~]# cp /etc/redis.conf /etc/redis/

再拷貝2個配置文件,共3個配置文件:
[root@node2 redis]# cp redis.conf redis.conf.2
[root@node2 redis]# cp redis.conf redis.conf.3
[root@node2 redis]# ls
redis.conf  redis.conf.2  redis.conf.3

準備存放數據目錄,並修改權限:
[root@node2 redis]# mkdir -pv /redis/db{1,2,3}
[root@node2 redis]# chown -R redis:redis /redis/db*

7.2 修改三個redis配置

第一個redis配置文件:
[root@node2 ~]# vim /etc/redis/redis.conf

#爲了方便監聽在0.0.0.0,建議如果配置多個IP監聽,將外網IP配置在前面,127.0.0.1配置在後面,IP中間用空格隔開
bind 0.0.0.0
dir /redis/db1
#後面要用命令啓動,需要設置開啓進程運行後臺功能
daemonize yes

第二個redis配置文件:
[root@node2 ~]# vim /etc/redis/redis.conf.2 

pidfile /var/run/redis/redis2.pid
port 6380
logfile /var/log/redis/redis2.log
dir /redis/db2
bind 0.0.0.0
daemonize yes

第三個redis配置文件:
拷貝redis.conf.2配置文件覆蓋redis.conf.3
[root@node2 ~]# cd /etc/redis
[root@node2 redis]# cp redis.conf.2 redis.conf.3
[root@node2 ~]# vim /etc/redis/redis.conf.3

pidfile /var/run/redis/redis3.pid
port 6381
logfile /var/log/redis/redis3.log
dir /redis/db3
daemonize yes

7.3 啓動服務,並配置sentinel

啓動第一個redis(主服務器):
[root@node2 ~]# redis-server /etc/redis/redis.conf

啓動第二個redis(從服務器):
[root@node2 ~]# redis-server /etc/redis/redis.conf.2

啓動第三個redis(從服務器):
[root@node2 ~]# redis-server /etc/redis/redis.conf.3
[root@node2 ~]# ss -tnlp | grep redis
LISTEN     0      128                       *:6379                     *:*      users:(("redis-server",19377,4))
LISTEN     0      128                       *:6380                     *:*      users:(("redis-server",19391,4))
LISTEN     0      128                       *:6381                     *:*      users:(("redis-server",19397,4))

7.4 連接配置

連接主服務器檢查狀態是不是主服務器:
[root@node2 ~]# redis-cli -h 10.201.106.22 -p 6379
10.201.106.22:6379> info replication
# Replication
role:master
……

第一個從服務器配置:
[root@node2 ~]# redis-cli -h 10.201.106.22 -p 6380
配置向哪個主服務器進行同步
10.201.106.22:6380> SLAVEOF 10.201.106.22 6379
OK

第二個從服務器配置:
10.201.106.22:6381> SLAVEOF 10.201.106.22 6379
OK

主服務器查看狀態:
10.201.106.22:6379> info replication
10.201.106.22:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.201.106.22,port=6380,state=online,offset=211,lag=1
slave1:ip=10.201.106.22,port=6381,state=online,offset=211,lag=0
……

7.5 測試同步

10.201.106.22:6379> SET ip 1.1.1.1
OK
查看已經能夠正常同步:
10.201.106.22:6380> GET ip
"1.1.1.1"
10.201.106.22:6381> GET ip
"1.1.1.1"

7.6 sentinel監控主節點

準備配置文件:
[root@node2 ~]# cp /etc/redis-sentinel.conf /etc/redis/

[root@node2 ~]# vim /etc/redis/redis-sentinel.conf 

#一個哨兵同意,就確定爲故障
sentinel monitor mymaster 10.201.106.22 6379 1

#設置5秒檢查不到主服務器,就將其down掉
sentinel down-after-milliseconds mymaster 5000

#並行度爲1
sentinel parallel-syncs mymaster 1

#判斷故障轉移失敗超時時間
sentinel failover-timeout mymaster 60000

啓動sentinel服務:
[root@node2 ~]# redis-sentinel /etc/redis/redis-sentinel.conf

連入sentinel:
[root@node2 ~]# redis-cli -h 10.201.106.22 -p 26379

查看配置信息:
10.201.106.22:26379> info

獲取master信息:
10.201.106.22:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "10.201.106.22"
    5) "port"
    6) "6379"
    7) "runid"
    8) "6afb08c6e2369213825dc8c08ca0fafede756569"
    9) "flags"
   10) "master"
   11) "pending-commands"
   12) "0"
   13) "last-ping-sent"
   14) "0"
   15) "last-ok-ping-reply"
   16) "603"
   17) "last-ping-reply"
   18) "603"
   19) "down-after-milliseconds"
   20) "5000"
   21) "info-refresh"
   22) "8121"
   23) "role-reported"
   24) "master"
   25) "role-reported-time"
   26) "521577"
   27) "config-epoch"
   28) "0"
   29) "num-slaves"
   30) "2"
   31) "num-other-sentinels"
   32) "0"
   33) "quorum"
   34) "1"
   35) "failover-timeout"
   36) "60000"
   37) "parallel-syncs"
   38) "1"

查看從節點服務器:
10.201.106.22:26379> SENTINEL slaves mymaster

7.7 故障轉移測試

kill主服務器進程:
[root@node2 ~]# ps aux | grep 6379
root     19377  0.1  0.3  33920  1748 ?        Ssl  05:53   0:04 redis-server 0.0.0.0:6379
[root@node2 ~]# kill 19377

在哨兵查看,6380端口(原第一從服務器)已經變成主服務器:
10.201.106.22:26379> INFO Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=10.201.106.22:6380,slaves=2,sentinels=1

查看主節點信息:
10.201.106.22:26379> SENTINEL masters

重新啓動10.201.106.22:6379(原主服務器)
[root@node2 ~]# redis-server /etc/redis/redis.conf

再次查看,不會切換,主節點還是6380端口:
10.201.106.22:26379> INFO Sentinel
10.201.106.22:26379> SENTINEL slaves mymaster

8、Clustering(分片)

分佈式解決方案:
Twemproxy(Twitter),不建議使用
Codis(豌豆莢,豆瓣),建議使用
Redis Cluster(官方)
Cerberus(芒果TV)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章