1. 程式人生 > 其它 >第二章 Redis資料型別

第二章 Redis資料型別

一、redis搭建

1.下載軟體包

下載Redis可以去Redis官網獲取原始碼包,下載到伺服器上編譯。Redis官網(https://redis.io/)。進入下載頁面(https://redis.io/download),從左到右分別是最新版、最新穩定版和容器版,我們可以下載最新穩定版的原始碼包(https://download.redis.io/releases/redis-6.0.9.tar.gz)。

[root@db01 ~]# rz redis-6.0.9.tar.gz
或者
[root@redis01 ~]# wget https://download.redis.io/releases/redis-6.0.9.tar.gz

2.安裝依賴

[root@redis01 ~]# yum install -y cpp binutils glibc glibc-kernheaders glibc-common glibc-devel gcc make tcl

3 更新gcc版本

centos7 預設的 gcc 版本小於 5.3 無法編譯,需要先安裝gcc新版才能編譯
[root@redis01 ~]# yum -y install centos-release-scl
[root@redis01 ~]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils

#臨時生效,退出 shell 或重啟會恢復原 gcc 版本
[root@redis01 ~]# scl enable devtoolset-9 bash

#永久生效
[root@redis01 ~]# echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile

4 .編譯安裝

[root@redis01 ~]# tar -zxvf redis-6.0.9.tar.gz
[root@redis01 ~]# mv redis-6.0.9 /usr/local/
[root@redis01 ~]# cd /usr/local/redis-6.0.9
[root@redis01 /usr/local/redis-6.0.9]# make &&make install  #預設安裝
或者
[root@redis01 ~]# make PREFIX=/usr/local/redis-6.0.9 install #指定目錄安裝

5.做軟連線

[root@redis01 /usr/local/redis-6.0.9]# cd ..
[root@redis01 /usr/local]# ln -s /usr/local/redis-6.0.9 /usr/local/redis

6.修改redis.conf

[root@redis01 /usr/local]# cd redis
[root@redis01 /usr/local/redis]# mkdir  /etc/redis/
[root@redis01 /usr/local/redis]# cp redis.conf /etc/redis/
[root@redis01 ~/redis-6.0.9]# vim /etc/redis/redis.conf
bind 127.0.0.1 #根據情況是否需要遠端訪問去掉註釋
requirepass 123456 #修改密碼
protected-mode no # 關閉protected-mode模式,此時外部網路可以直接訪問
daemonize no      #以守護程序模式啟動,指定目錄安裝時改為yes

7. 配置system啟動

[root@redis01 /usr/local/redis]# vim /etc/systemd/system/redis.service
[Unit]
Description=Redis
After=network.target

[Service]
#Type=forking
ExecStart=/usr/local/redis-6.0.9/src/redis-server /etc/redis/redis.conf
ExecReload=/usr/local/redis-6.0.9/src/redis-server -s reload
ExecStop=/usr/local/redis-6.0.9/src/redis-server -s stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target

注意Type=forking不註釋掉 服務無法啟動

使服務自動執行
[root@redis01 ~]# systemctl daemon-reload
[root@redis01 ~]# systemctl enable redis

啟動服務
[root@redis01 ~]# systemctl restart redis
[root@redis01 ~]# systemctl status redis

驗證服務
[root@redis01 /usr/local/redis]# netstat  -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      12768/redis-server  

8.連線redis

#連線
[root@redis01 /usr/local/redis]# redis-cli -p 6379
127.0.0.1:6379> auth 123456			#驗證密碼
127.0.0.1:6379>

9.關閉redis

[root@redis01 /usr/local/redis]# redis-cli shutdown
或
[root@db01 redis]# redis-cli 
127.0.0.1:6379> shutdown

二、redis配置檔案

1.配置

#預設的配置檔案
[root@redis01 redis]# pwd
/usr/local/redis
[root@redis01 redis]# ll
-rw-rw-r--  1 root root 46695 Jun 13  2018 redis.conf

#建立reids配置檔案目錄
[root@redis01 redis]# mkdir /service/redis/6379 -p

#編寫配置檔案
[root@redis01 redis]# vim /service/redis/6379/redis.conf
bind 172.16.1.51 127.0.0.1							#監聽地址
port 6379										   #埠
daemonize no									   #後臺啟動
pidfile /service/redis/6379/redis_6379.pid		 	  #指定pid檔案
loglevel notice										#指定日誌級別
logfile /service/redis/6379/redis_6379.log			  #指定日誌檔案

2.指定配置檔案啟動

[root@redis01 redis]# redis-server /service/redis/6379/redis.conf

三、redis操作

1.基本操作

1.連線redis
	[root@db01 redis]# redis-cli 
    127.0.0.1:6379>
2.檢視所有資料
    127.0.0.1:6379> keys *
    (empty list or set)
	#檢視時注意不要輕易使用,如想檢視資料,先檢視資料量DBSIZE
	127.0.0.1:6379> DBSIZE
	(integer) 2018041
3.新增資料
    127.0.0.1:6379> set k1 v1
    OK
4.檢視資料
    127.0.0.1:6379> keys *
    1) "k1"
    127.0.0.1:6379> get k1
    "v1"
5.刪除資料
    127.0.0.1:6379> keys *
    1) "k1"
    127.0.0.1:6379> DEL k1
    (integer) 1
    127.0.0.1:6379> keys *
    (empty list or set)
6.修改資料
	127.0.0.1:6379> set k1 v1
    OK
    127.0.0.1:6379> set k1 v11111
    OK
    127.0.0.1:6379> get k1
    "v11111"
7.追加資料
	127.0.0.1:6379> APPEND k1 000000
    (integer) 12
    127.0.0.1:6379> get k1
    "v11111000000"
8.切換庫
    127.0.0.1:6379> SELECT 1
    OK
    127.0.0.1:6379[1]> SELECT 2
    OK
    127.0.0.1:6379[2]> SELECT 3
    OK
    127.0.0.1:6379> SELECT 16
    (error) ERR invalid DB index

2.密碼的設定

1.配置檔案配置密碼
    [root@db01 redis]# vim redis.conf 
    requirepass 123
2.使用密碼連線
	[root@db01 redis]# redis-cli -a 123
3.登陸後輸入密碼
	[root@db01 redis]# redis-cli
    127.0.0.1:6379> AUTH 123
    OK
    127.0.0.1:6379> DBSIZE
    (integer) 2018041
4.redis連線後獲取密碼
    127.0.0.1:6379> CONFIG GET requirepass
    1) "requirepass"
    2) "123"
5.redis連線後修改密碼
    127.0.0.1:6379> CONFIG set requirepass 234
    OK
    [root@db01 redis]# redis-cli
	127.0.0.1:6379> DBSIZE
    (error) NOAUTH Authentication required.
    127.0.0.1:6379> auth 123
    (error) ERR invalid password
    127.0.0.1:6379> auth 234
    OK

3.通用操縱

1.判斷key是否存在
    127.0.0.1:6379> EXISTS k1
    (integer) 1						#存在則返回1
    127.0.0.1:6379> EXISTS k2
    (integer) 0						#不存在則返回0
2.修改key的名字
	127.0.0.1:6379> KEYS *
    1) "k1"
    127.0.0.1:6379> RENAME k1 k100
    OK
    127.0.0.1:6379> KEYS *
    1) "k100"
3.檢視資料型別
	127.0.0.1:6379> TYPE k100
    string
4.設定生存時間
	#以秒為單位
    127.0.0.1:6379> EXPIRE qiudao 10
    (integer) 1
    #以毫秒為單位
    127.0.0.1:6379> PEXPIRE k100 10000
	(integer) 1
5.檢視生存時間
	127.0.0.1:6379> TTL k100
    (integer) 1					#正整數生存時間倒計時
    127.0.0.1:6379> TTL k100
    (integer) -1				#-1代表沒有設定生存時間
    127.0.0.1:6379> TTL k100
    (integer) -2				#代表設定過生存時間已刪除,已過期
6.取消生存時間
	127.0.0.1:6379> TTL qiudao
    (integer) 93
    127.0.0.1:6379> PERSIST qiudao
    (integer) 1
    127.0.0.1:6379> TTL qiudao
    (integer) -1

四、Redis資料持久化

1.Redis資料安全問題

	前面我們提到,Redis是一個快取中介軟體,它的最大特點是使用記憶體從而使其效能強悍。但是使用記憶體的方式有一個致命的特點就是資料沒辦法持久化儲存。然而Redis持久化儲存有兩種持久化方案,RDB(Redis DataBase)和 AOF(Append-Only File)。其中RDB是將記憶體中的資料進行快照儲存到磁碟,AOF則為可回放的命令日誌記錄redis內的所有操作。它們各有特點也相互獨立。Redis4之後支援RDB-AOF混合持久化的方式,結合了兩者的優點,可以通過 aof-use-rdb-preamble 配置項可以開啟混合開關。

2.什麼是持久化

將記憶體中的資料寫入到磁碟,永久儲存

3.持久化的模式

1.RDB模式
2.AOF模式

4.快照持久化(RDB)

1) RDB概述

RDB(Redis DataBase)是將Redis記憶體中的資料進行Snaptshot快照儲存在磁碟內,是Redis的預設持久化方案。使用RDB持久化預設有三種策略,該持久化策略在redis.conf中可配置,會以一段時間內有指定次資料修改的規則觸發快照動作,快照檔名為dump.rdb,該檔案預設使用LZF壓縮演算法 。每當Redis服務重啟的時候會從該檔案中載入資料進記憶體。

RDB持久化除了可以根據配置中的策略觸發,也可以手動觸發,使用save和bgsave命令即可。這兩個命令的區別的save會阻塞伺服器程序,在進行save的過程中,伺服器不能處理任何請求,而bgsave會通過一個子程序在後臺處理rdb持久化。事實上save和bgsave呼叫的都是rdbSave函式,因此Redis不允許save和bgsave同時執行,這也是為了避免出現競爭導致rdb檔案資料不準確。

bgsave操作使用CopyOnWrite機制進行寫時複製,是由一個子程序將記憶體中的最新資料遍歷寫入臨時檔案,此時父程序仍舊處理客戶端的操作,當子程序操作完畢後再將該臨時檔案重新命名為dump.rdb替換掉原來的dump.rdb檔案,因此無論bgsave是否成功,dump.rdb都不會受到影響。

另外在主從全量同步、debug reload以及shutdown的情況下也會觸發RDB資料持久化。

2)RDB模式

可以在指定的時間間隔內生成資料集的時間點快照(point-in-time snapshot)

3)RDB工作模式

1.預設情況下,Redis儲存資料集快照到磁碟,名為dump.rdb的二進位制檔案。你可以設定讓Redis在N秒內至少有M次資料集改動時儲存資料集,或者你也可以手動呼叫SAVE或者BGSAVE命令。

2.在上文中我們已經在配置檔案中做過對應的配置:
例如,這個配置會讓Redis在每個60秒內至少有1000次鍵改動時自動轉儲資料集到磁碟:
save 60 1000

3.當 Redis 需要儲存 dump.rdb 檔案時,伺服器執行以下操作:
Redis 呼叫 fork() ,同時擁有父程序和子程序。
子程序將資料集寫入到一個臨時的 RDB 檔案中。當子程序完成對新 RDB 檔案的寫入時, Redis 用新RDB 檔案替換原來的 RDB 檔案,並刪除舊的 RDB 檔案。

4.這種方式使得 Redis 可以從寫時複製機制中獲益。

4) 快照持久化快照相關配置

#編輯配置檔案
[root@db01 ~]# vim /service/redis/6379/redis.conf 
bind 172.16.1.51 127.0.0.1
port 6379
daemonize yes
pidfile /service/redis/6379/redis_6379.pid
loglevel notice
logfile /service/redis/6379/redis_6379.log
requirepass 123
dir "/etc/redis"
dbfilename dump.rdb
stop-write-on-bgsave-error yes 
rdbchecksum yes
rdbcompression yes
save 900 1
save 300 10
save 60 10000

save m n
#配置快照(rdb)促發規則,格式:save <seconds> <changes>

#save 900 1 900秒內至少有1個key被改變則做一次快照
#save 300 10 300秒內至少有300個key被改變則做一次快照
#save 60 10000 60秒內至少有10000個key被改變則做一次快照

#關閉該規則使用svae “” 

dbfilename dump.rdb
#rdb持久化儲存資料庫檔名,預設為dump.rdb

stop-write-on-bgsave-error yes 
#yes代表當使用bgsave命令持久化出錯時候停止寫RDB快照檔案,no表明忽略錯誤繼續寫檔案。

rdbchecksum yes
#在寫入檔案和讀取檔案時是否開啟rdb檔案檢查,檢查是否有無損壞,如果在啟動是檢查發現損壞,則停止啟動。

dir "/etc/redis"
#資料檔案存放目錄,rdb快照檔案和aof檔案都會存放至該目錄,請確保有寫許可權

rdbcompression yes
#是否開啟RDB檔案壓縮,該功能可以節約磁碟空間、

5)使用RDB檔案

1.先停止redis
2.將rdb檔案放到指定目錄下
3.啟動redis

6) RDB優點

1.RDB是一種表示某個即時點的Redis資料的緊湊檔案。RDB檔案適合用於備份。例如,你可能想要每小時歸檔最近24小時的RDB檔案,每天儲存近30天的RDB快照。這允許你很容易的恢復不同版本的資料集以容災。
2.RDB非常適合於災難恢復,作為一個緊湊的單一檔案,可以被傳輸到遠端的資料中心。
3.RDB最大化了Redis的效能,因為Redis父程序持久化時唯一需要做的是啟動(fork)一個子程序,由子程序完成所有剩餘工作。父程序例項不需要執行像磁碟IO這樣的操作。
4.RDB在重啟儲存了大資料集的例項時比AOF要快。

7)RDB缺點

1.當你需要在Redis停止工作(例如停電)時最小化資料丟失,RDB可能不太好。你可以配置不同的儲存點(save point)來儲存RDB檔案(例如,至少5分鐘和對資料集100次寫之後,但是你可以有多個儲存點)。然而,你通常每隔5分鐘或更久建立一個RDB快照,所以一旦Redis因為任何原因沒有正確關閉而停止工作,你就得做好最近幾分鐘資料丟失的準備了。
2.RDB需要經常呼叫fork()子程序來持久化到磁碟。如果資料集很大的話,fork()比較耗時,結果就是,當資料集非常大並且CPU效能不夠強大的話,Redis會停止服務客戶端幾毫秒甚至一秒。AOF也需要fork(),但是你可以調整多久頻率重寫日誌而不會有損(trade-off)永續性(durability)。

8) RDB優缺點總結

優點:速度快,適合於用作備份,主從複製也是基於RDB持久化功能實現的。

缺點:會有資料丟失、導致服務停止幾秒

9)停止備份

在配置檔案中就設定save “”或在命令列中 config set save “”。

10) 手動開始備份

save:會立即生成dump.rdb,但是會阻塞往redis記憶體中寫入資料。
bgsave:後臺非同步備份。

如果是使用flushdb命令,會把之前的快照更新成當前的空狀態,所以執行了flushdb後更新的快照是沒有資料的。

11) save與bgsave對比

命令 save bgsave
IO型別 同步 非同步
是否阻塞 否(阻塞發生在fork)
優點 不會消耗額外記憶體 不阻塞客戶端命令
缺點 阻塞客戶端命令 建立fork,消耗記憶體

5. AOF持久化

	AOF(Append-Only File)記錄Redis中每次的寫命令,類似mysql中的binlog,服務重啟時會重新執行AOF中的命令將資料恢復到記憶體中,RDB(按策略持久化)持久化方式記錄的粒度不如AOF(記錄每條寫命令),因此很多生產環境都是開啟AOF持久化。AOF中記錄了操作和資料,在日誌檔案中追加完成後才會將記憶體中的資料進行變更。
	AOF(append only file)只追加檔案,記錄伺服器執行的所有寫操作命令,並在伺服器啟動時,通過重新執行這些命令來還原資料集。 AOF 檔案中的命令全部以 Redis 協議的格式來儲存,新命令會被追加到檔案的末尾。

1)AOF原理

1.客戶端的請求寫命令會被append追加到AOF緩衝區內;

2.AOF緩衝區根據AOF持久化策略[always,everysec,no]將操作sync同步到磁碟的AOF檔案中;

3.AOF檔案大小超過重寫策略或手動重寫時,會對AOF檔案rewrite重寫,壓縮AOF檔案容量;

4.Redis服務重啟時,會重新load載入AOF檔案中的寫操作達到資料恢復的目的;

2) AOF配置

開啟了AOF之後,RDB就預設不使用了。使用下面的配置開啟AOF以及策略。(如果使用AOF,推薦選擇always方式持久化,否則在高併發場景下,每秒鐘會有幾萬甚至百萬條請求,如果使用everysec的方式的話,萬一伺服器掛了那幾萬條資料就丟失了)。

#開啟AOF持久化
appendonly yes

#AOF檔名
appendfilename "appendonly.aof"

#AOF檔案儲存路徑 與RDB是同一個引數
dir "/opt/app/redis6/data"

#AOF策略,一般都是選擇第一種[always:每個命令都記錄],[everysec:每秒記錄一次],[no:看機器的心情高興了就記錄]

appendfsync always
#appendfsync everysec
# appendfsync no

#aof檔案大小比起上次重寫時的大小,增長100%(配置可以大於100%)時,觸發重寫。[假如上次重寫後大小為10MB,當AOF檔案達到20MB時也會再次觸發重寫,以此類推]
auto-aof-rewrite-percentage 100 

#aof檔案大小超過64MB時,觸發重寫
auto-aof-rewrite-min-size 64mb 

#是否在後臺寫時同步單寫,預設值no(表示需要同步).這裡的後臺寫,表示後臺正在重寫檔案(包括bgsave和bgrewriteaof.bgrewriteaof網上很多資料都沒有涉及到。其實關掉bgsave之後,主要的即是aof重寫檔案了).no表示新的主程序的set操作會被阻塞掉,而yes表示新的主程序的set不會被阻塞,待整個後臺寫完成之後再將這部分set操作同步到aof檔案中。但這可能會存在資料丟失的風險(機率很小),如果對效能有要求,可以設定為yes,僅在後臺寫時會非同步處理命令.
no-appendfsync-on-rewrite no

# 指redis在恢復時,會忽略最後一條可能存在問題的指令。預設值yes。即在aof寫入時,可能存在指令寫錯的問題(突然斷電,寫了一半),這種情況下,yes會log並繼續,而no會直接恢復失敗.
aof-load-truncated

3)AOF持久化策略

AOF分別有三種備份策略,分別是[always:每個命令都記錄],[everysec:每秒記錄一次],[no:看機器的心情高興了就記錄],針對這三種策略給出如下說明。

4)策略說明

策略 說明 優點
always 每次執行,都會持久化到AOF檔案中 不丟失資料
everysec 每秒持久化一次 減少IO
no 根據伺服器效能持久化 全自動

5)策略抉擇

命令 Always Everysec no
優點 不丟失資料 每秒一次fsync,減少IO 不用管,全自動
缺點 IO開銷大 丟1秒鐘的資料 不可控

6)AOF模式的優點

1.使用AOF Redis會更具有可永續性(durable):你可以有很多不同的fsync策略:沒有fsync,每秒fsync,每次請求時fsync。使用預設的每秒fsync策略,寫效能也仍然很不錯(fsync是由後臺執行緒完成的,主執行緒繼續努力地執行寫請求),即便你也就僅僅只損失一秒鐘的寫資料。
2.AOF日誌是一個追加檔案,所以不需要定位,在斷電時也沒有損壞問題。即使由於某種原因檔案末尾是一個寫到一半的命令(磁碟滿或者其他原因),redis-check-aof工具也可以很輕易的修復。
3.當AOF檔案變得很大時,Redis會自動在後臺進行重寫。重寫是絕對安全的,因為Redis繼續往舊的檔案中追加,使用建立當前資料集所需的最小操作集合來建立一個全新的檔案,一旦第二個檔案建立完畢,Redis就會切換這兩個檔案,並開始往新檔案追加。
4.AOF檔案裡面包含一個接一個的操作,以易於理解和解析的格式儲存。你也可以輕易的匯出一個AOF檔案。例如,即使你不小心錯誤地使用FLUSHALL命令清空一切,如果此時並沒有執行重寫,你仍然可以儲存你的資料集,你只要停止伺服器,刪除最後一條命令,然後重啟Redis就可以。

7)AOF重寫

1.因為 AOF 的運作方式是不斷地將命令追加到檔案的末尾,所以隨著寫入命令的不斷增加, AOF 檔案的體積也變得越來越大。舉個例子,如果你對一個計數器呼叫了 100 次 INCR ,那麼僅僅是為了儲存這個計數器的當前值, AOF 檔案就需要使用 100 條記錄。然而在實際上,只使用一條 SET 命令已經足以儲存計數器的當前值了,其餘 99 條記錄實際上都是多餘的。

2.為了處理這種情況, Redis 支援一種有趣的特性:可以在不斷服務客戶端的情況下,對 AOF 檔案進行重建。執行 BGREWRITEAOF 命令, Redis 將生產一個新的 AOF 檔案,這個檔案包含重建當前資料集所需的最少命令。

8) AOF重寫配置

配置名 含義
appendonly 開啟AOF持久化功能
auto-aof-rewrite-min-size 觸發重寫的最小尺寸
auto-aof-rewrite-percentage AOF檔案增長率
aof_current_size AOF當前尺寸
aof_base_size AOF上次啟動和重寫的尺寸(單位:位元組)

9) AOF重寫觸發機制

根據配置,AOF持久化觸發機制如下:

1.aof_current_size > auto-aof-rewrite-min-size
2.(aof_current_size - aof_base_size) / aof_base_size > auto-aof-rewrite-percentage

10) AOF重寫流程

12)AOF持久化缺點

1.對同樣的資料集,AOF檔案通常要大於等價的RDB檔案。
2.AOF可能比RDB慢,這取決於準確的fsync策略。通常fsync設定為每秒一次的話效能仍然很高,如果關閉fsync,即使在很高的負載下也和RDB一樣的快。不過,即使在很大的寫負載情況下,RDB還是能提供能好的最大延遲保證。
3.在過去,我們經歷了一些針對特殊命令(例如,像BRPOPLPUSH這樣的阻塞命令)的罕見bug,導致在資料載入時無法恢復到儲存時的樣子。這些bug很罕見,我們也在測試套件中進行了測試,自動隨機創造複雜的資料集,然後載入它們以檢查一切是否正常,但是,這類bug幾乎不可能出現在RDB持久化中。為了說得更清楚一點:Redis AOF是通過遞增地更新一個已經存在的狀態,像MySQL或者MongoDB一樣,而RDB快照是一次又一次地從頭開始創造一切,概念上更健壯。
	但是,
	1)要注意Redis每次重寫AOF時都是以當前資料集中的真實資料從頭開始,相對於一直追加的AOF檔案(或者一次重寫讀取老的AOF檔案而不是讀記憶體中的資料)對bug的免疫力更強。
	2)我們還沒有收到一份使用者在真實世界中檢測到崩潰的報告。

13)AOF持久化優缺點總結

優點:可以最大程度保證資料不丟失
缺點:日誌記錄量級比較大

6.RDB與AOF抉擇

1) RDB與AOF比較

命令 RDB AOF
啟動優先順序
體積
恢復速度
資料安全性 丟資料 根據策略的不同,丟資料的情況也不同
輕重

2) RDB與AOF之間的優劣勢

#1.RDB的優點
1.壓縮後的二進位制檔案,適用於備份、全量複製及災難恢復。
2.RDB恢復資料效能優於AOF方式。

#2.RDB的缺點
1.無法做到實時持久化,每次都要建立子程序,頻繁操作成本過高
2.儲存後的二進位制檔案,不同版本直接存在相容性問題

#3.AOF的優點
1.以文字形式儲存,易讀
2.記錄寫操作保證資料不丟失

#4.AOF的缺點
1.儲存所有寫操作命令,且檔案為文字格式儲存,未經壓縮,檔案體積高。
2.恢復資料時重放AOF中所有程式碼,恢復效能弱於RDB方式。

7. AOF與RDB混合

	看了上面的RDB和AOF的介紹後,我們可以發現,使用RDB持久化會有資料丟失的風險,但是恢復速度快,而使用AOF持久化可以保證資料完整性,但恢復資料的時候會很慢。於是從Redis4之後新增了混合AOF和RDB的模式,先使用RDB進行快照儲存,然後使用AOF持久化記錄所有的寫操作,當重寫策略滿足或手動觸發重寫的時候,將最新的資料儲存為新的RDB記錄。這樣的話,重啟服務的時候會從RDB何AOF兩部分恢復資料,即保證了資料完整性,又提高了恢復的效能。
	
	開啟混合模式後,每當bgrewriteaof命令之後會在AOF檔案中以RDB格式寫入當前最新的資料,之後的新的寫操作繼續以AOF的追加形式追加寫命令。當redis重啟的時候,載入 aof 檔案進行恢復資料:先載入 rdb 的部分再載入剩餘的 aof部分。

1)混合配置

修改下面的引數即可開啟AOF,RDB混合持久化
aof-use-rdb-preamble yes

2) 混合模式的使用

開啟混合持久化模式後,重寫之後的aof檔案裡和rdb一樣儲存二進位制的快照資料,繼續往redis中進行寫操作,後續操作在aof中仍然是以命令的方式追加。因此重寫後aof檔案由兩部分組成,一部分是類似rdb的二進位制快照,另一部分是追加的命令文字。

\# step: 進入Redis, 寫入資料
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> set name alvin
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> set add 上海
OK
127.0.0.1:6379> exit
\# Step 2: 檢視備份檔案

[root@alvin-test-os redis]# ll data/
總用量 8
-rw-r--r--. 1 root root 121 11月 24 15:39 appendonly.aof
-rw-r--r--. 1 root root 116 11月 24 15:39 dump.rdb

[root@alvin-test-os redis]# cat data/appendonly.aof | grep add
add
[root@alvin-test-os redis]# cat data/appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$5
alvin
*3
$3
set
$3
age
$2
18
*3
$3
set
$3
add
$6
上海

# Step 3: 啟動備份
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
127.0.0.1:6379> exit

# Step 4: 檢視配置檔案發現AOF備份檔案變成了二進位制檔案
[root@alvin-test-os redis]# cat data/appendonly.aof
REDIS0009�  redis-ver6.0.9�
�edis-bits�@�ctime��_used-mem��4
 aof-preamble���namealvinadd上海age���6����&[root@alvin-test-os redis]#

# Step 5: 再次寫入檔案
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> set company 上海
OK
127.0.0.1:6379> exit

# Step 6:再次檢視備份檔案發現被分成了兩份,一份二進位制,一份AOF備份
[root@alvin-test-os redis]# cat data/appendonly.aof
REDIS0009�  redis-ver6.0.9�
�edis-bits�@�ctime��_used-mem��4
 aof-preamble���namealvinadd上海age���6����&*2
$6
SELECT
$1
0
*3
$3
set
$7
company
$15
上海
[root@alvin-test-os redis]#

3)備份Redis資料

1.Redis 對於資料備份是非常友好的,因為你可以在伺服器執行的時候對 RDB 檔案進行復制: RDB 檔案一旦被建立,就不會進行任何修改。
2.當伺服器要建立一個新的 RDB 檔案時,它先將檔案的內容儲存在一個臨時檔案裡面,當臨時檔案寫入完畢時,程式才使用臨時檔案替換原來的 RDB 檔案。
3.這也就是說,無論何時, 複製 RDB 檔案都是絕對安全的。

#以下是我們的建議:
1.建立一個定期任務(cron job), 每小時將一個 RDB 檔案備份到一個資料夾, 並且每天將一個 RDB 檔案備份到另一個資料夾。
2.確保快照的備份都帶有相應的日期和時間資訊, 每次執行定期任務指令碼時, 使用 find 命令來刪除過期的快照: 比如說, 你可以保留最近 48 小時內的每小時快照, 還可以保留最近一兩個月的每日快照。
3.至少每天一次, 將 RDB 備份到你的資料中心之外, 或者至少是備份到你執行 Redis 伺服器的物理機器之外。

4)RDB持久化高階配置

#編輯配置檔案
[root@db01 redis]# vim /etc/redis/6379/redis.conf
#後臺備份程序出錯時,主程序停不停止寫入? 主程序不停止容易造成資料不一致
stop-writes-on-bgsave-error yes
#匯出的rdb檔案是否壓縮 如果rdb的大小很大的話建議這麼做
rdbcompression yes
#匯入rbd恢復時資料時,要不要檢驗rdb的完整性 驗證版本是不是一致
rdbchecksum yes

5)AOF持久化高階配置

#編輯配置檔案
[root@db01 redis]# vim /etc/redis/6379/redis.conf
#正在匯出rdb快照的過程中,要不要停止同步aof
no-appendfsync-on-rewrite yes
#aof檔案大小比起上次重寫時的大小,增長率100%時重寫,缺點:業務開始的時候,會重複重寫多次
auto-aof-rewrite-percentage 100
#aof檔案,至少超過64M時,重寫
auto-aof-rewrite-min-size 64mb

五、資料型別

1.Redis資料結構之字串

Redis的String型別可以是字串(簡單的字串、複雜的字串(例如JSON、XML))、數字(整數、浮點數),甚至是二進位制(圖片、音訊、視訊),但是值最大不能超過512MB。

1) 命令列模式

進入命令列模式:
#a 輸入密碼
redis-cli -a password_value
 
#raw 避免中文顯示亂碼
redis-cli -a password_value --raw

2) 檢視命令幫助

127.0.0.1:6379> help @string

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

  BITCOUNT key [start end]
  summary: Count set bits in a string
  since: 2.6.0

  BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]

3) Exists

#檢視key是否存在,返回true / false(0/1)

127.0.0.1:6379> EXISTS a
1
127.0.0.1:6379> EXISTS b
0

4)TTL

#檢視資料過期時間

127.0.0.1:6379> ttl a
-1 		# 永不過期

127.0.0.1:6379> ttl b
(integer) 2 	# 過期時間還有2個單位

5)增加資料

增加資料的命令有以下幾個:set,setex,psetex,setnx。

#ex為多少秒過期 px為多少毫秒過期,nx為若不存在才建立,xx為若存在才覆蓋建立
set key value [ex seconds] [px milliseconds] [nx|xx]

1.使用set命令新增一個鍵值對及其EX,PX用法
# 設定
127.0.0.1:6379> set name 金輝
OK
127.0.0.1:6379> get name
金輝

# 設定過期時間為秒
127.0.0.1:6379> set name 金輝 ex 10
OK
127.0.0.1:6379> ttl name
6
127.0.0.1:6379> ttl name
-2 

# set 和 ex合併成setex
127.0.0.1:6379> SETEX name 10 金輝
OK
127.0.0.1:6379> ttl name
5
127.0.0.1:6379> ttl name
-2

# 設定過期時間為毫秒
127.0.0.1:6379> set name 金輝 px 10
OK
127.0.0.1:6379> TTL name
-2

# set 和 px 合併使用
127.0.0.1:6379> PSETEX name 100 金輝
OK
127.0.0.1:6379> ttl name
-2

2.使用set命令新增一個鍵值對及其NX,XX用法
Nx:當key不存在時建立,已存在則忽略。
Xx:當key存在則更新,不存在則忽略。

# nx
127.0.0.1:6379> set name alvin nx
OK
127.0.0.1:6379> get name
alvin
127.0.0.1:6379> set name 金輝
OK
127.0.0.1:6379> get name
金輝
127.0.0.1:6379> set name alvin nx

127.0.0.1:6379> get name
金輝

# set 與 nx 合併使用
127.0.0.1:6379> setnx name alvin
(integer) 0
127.0.0.1:6379> get name
金輝

3.批量增加
同時定義多個鍵值對,mset也可以和nx一起用。
mset key1 value1 [key2 value2...] #批量建立kv,已存在的會被更新
msetnx key1 value1 [key2 value2...] #批量建立kv,所有key不存在才會建立

127.0.0.1:6379> mset k1 a k2 b k3 c
OK
127.0.0.1:6379> mget k1 k2 k3
1) "a"
2) "b"
3) "c"

6) 刪除資料

DDL			#刪除資料

使用del命令刪除資料,可批量可單個刪除。

#格式
del key1 [key2 key3...]

#案例
127.0.0.1:6379> del k1 k2 k3
(integer) 3
127.0.0.1:6379> del name_xx
(integer) 1
127.0.0.1:6379> mget k1 k2 k3 name_xx name_nx
1) (nil)
2) (nil)
3) (nil)
4) (nil)
5) "wyk"

7)更改資料

#1.使用set命令修改資料
127.0.0.1:6379> set name alvin
OK
127.0.0.1:6379> get name
"alvin"
127.0.0.1:6379> set name alvin
OK
127.0.0.1:6379> get name
"alvin"

#2.使用getset命令修改資料
等同於get+set,執行此命令返回get的結果,然後將該key更新為新的value,下次再get的時候查到的就是新的value。
127.0.0.1:6379> GETSET name alvin
金輝
127.0.0.1:6379>

#3.使用setrange按下標更新資料
對指定下標的字串進行更新,下標從0開始算起。
127.0.0.1:6379> SETRANGE name 5 alvin
10
127.0.0.1:6379> get name
alvinalvin

8)查詢資料

#1.檢視所有的key
檢視所有的Key,在資料量大的Redis中慎用,容易卡死。
127.0.0.1:6379> KEYS *
1) "name"
2) "a"

#2.根據key獲取資料
使用get獲得指定key的value。
127.0.0.1:6379> get key

#3.批量獲得指定keys的values
mget key1 [key2 key3...]
127.0.0.1:6379> MGET a name
b
alvinalvin
127.0.0.1:6379>

#4.從字串的指定開始結束下標擷取字串
getrange key start end
127.0.0.1:6379> GETRANGE name 1 4
lvin
127.0.0.1:6379>

9)計數

#1.指定key遞增
對指定的key的value加1,遞增步長預設1,如果key不存在,其初始值為0,在incr之後其值為1,如果value的值不能轉為整型,如hello,該操作將執行失敗並返回相應的錯誤資訊。

127.0.0.1:6379> INCR num
1
127.0.0.1:6379> INCR num
2

#2.指定key遞減
對指定的key的value減1,遞減步長預設1,如果key不存在,其初始值為0,在decr之後其值為-1,如果value的值不能轉為整型,如hello,該操作將執行失敗並返回相應的錯誤資訊。

127.0.0.1:6379> DECR num
1
127.0.0.1:6379> DECR num
0

#3.遞增指定長度
對指定的key的value加指定的步長,遞增步長可指定,如果key不存在,其初始值為0,在incrby之後其值為步長,如果value的值不能轉為整型,如hello,該操作將執行失敗並返回相應的錯誤資訊。

$步長increment為整數,當為負數時效果等於遞減
incrby key increment

#4.遞減指定長度
對指定的key的value減指定的步長,遞減步長可指定,如果key不存在,其初始值為0,在decrby之後其值為步長的負數,如果value的值不能轉為整型,如hello,該操作將執行失敗並返回相應的錯誤資訊。

$步長increment為整數,當為負數時效果等於遞増

decrby key increment

redis> SET count 100
OK

redis> DECRBY count 20
(integer) 80

10) 追加

#在字串最後面追加子串
append key value

# 對不存在的 key 執行 APPEND
## 確保 myphone 不存在
redis> EXISTS myphone
(integer) 0

# 對不存在的 key 進行 APPEND ,等同於 SET myphone "nokia"
## 字元長度
redis> APPEND myphone "nokia" 
(integer) 5

# 對已存在的字串進行 APPEND
## 長度從 5 個字元增加到 12 個字元
redis> APPEND myphone " - 1110" 
(integer) 12

redis> GET myphone
"nokia - 1110"

11) 長度

#返回字元的長度

strlen key

2.Redis資料結構之雜湊

雜湊型別是指鍵值對裡的value本身儲存的也是一個個的KV鍵值對,類似於python中的dict和java中的map集合。

1)檢視命令幫助

not connected> help @hash

  HDEL key field [field ...]
  summary: Delete one or more hash fields
  since: 2.0.0

  HEXISTS key field
  summary: Determine if a hash field exists
  since: 2.0.0

2) 檢視hash型別的key中指定的field是否存在

hexists key field
127.0.0.1:6379> HEXISTS csdn name
1

127.0.0.1:6379> HEXISTS csdn company
1

3) 設定hash型別的單個field或一次性設定多個field

HSET key field value [field value ...]
 
hset csdn id 1 name Alvin company 上海

4) 只有value中不存在的field才會被建立

HSETNX key field value

5) 刪除資料

#使用hdel命令刪除hash型別的value中的fields,可批量可單個刪除
HDEL key field1 [field2 ...]

127.0.0.1:6379> HDEL csdn name
1
127.0.0.1:6379> HEXISTS csdn name
0

6)更改資料

#對hash型別中相同的field進行set操作會更新該field的值
HSET key field value [field value ...]

7) 查詢資料

#1.使用hget獲取指定hash型別的field對應的值
HGET key field

127.0.0.1:6379> HGET csdn company
上海

#2.使用hmget獲取指定hash型別的多個field對應的值
HMGET key field [field ...]

127.0.0.1:6379> HMGET csdn company id
上海
1

#3.使用hgetall獲得指定hash型別物件的全部field和對應的value值
HGETALL key

127.0.0.1:6379> HGETALL csdn
id
1
company
上海

#4.使用hkeys獲得指定hash型別物件的全部field
HKEYS key

127.0.0.1:6379> HKEYS csdn
id
company

#5.使用hvals獲得指定hash型別物件的全部field的values值
HVALS key

127.0.0.1:6379> HVALS csdn
1
上海

8) 計數

#1.hincrby可以對hash物件的指定的field的value做遞增操作
與string型別中的incrby類似,hincrby可以對hash物件的指定的field的value做遞增操作,increment必須是整數(hash型別中沒有hdecrby方法,當increment為負數時為遞減操作),value必須是integer型別,否則會報對應的錯誤。
HINCRBY key field increment

ps:filed對應的value必須是integer型別,increment必須是整數,可以為負

127.0.0.1:6379> HINCRBY csdn  id 10
11

#2.hincrbyfloat可以對hash物件的指定的field的value做遞增操作
與string型別中的incrbyfloat類似,hincrbyfloat可以對hash物件的指定的field的value做遞增操作,increment可以是整數或浮點數(hash型別中沒有hdecrbyfloat方法,當increment為負數時為遞減操作),value必須是數字型別,否則會報對應的錯誤。
HINCRBYFLOAT key field increment

ps:filed對應的value必須是數字型別,increment可以是整數或浮點,可以為負

127.0.0.1:6379> HINCRBYFLOAT csdn id 10.9
21.9

9) 長度

#1.hlen返回hash型別中field的數量
HLEN key

127.0.0.1:6379> HLEN csdn
2

#2.hstrlen返回hash型別中指定filed對應的value的字元長度
HSTRLEN key field

127.0.0.1:6379> HSTRLEN csdn id
4
127.0.0.1:6379> HSTRLEN csdn company
15

10) 過期

#我們可以看到hash型別沒有hsetex hpsetex一類的方法,想對hash物件做過期策略可以使用全域性函式expire。
expire key seconds

127.0.0.1:6379> EXPIRE csdn 1000
1
127.0.0.1:6379> ttl csdn
987

3.Redis資料結構之列表

Redis列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊)一個列表最多可以包含 2^32 - 1 個元素 (4294967295, 每個列表超過40億個元素)。

1)檢視命令幫助

help @list

  BLPOP key [key ...] timeout
  summary: Remove and get the first element in a list, or block until one is available
  since: 2.0.0

  BRPOP key [key ...] timeout
  summary: Remove and get the last element in a list, or block until one is available
  since: 2.0.0

2)從左邊插入元素

從左邊插入元素,從左邊依次追加進棧,先進後出,後進先出
LPUSH key element [element ...]
 
127.0.0.1:6379> LPUSH mylist alvin 18
3
127.0.0.1:6379> LPUSH mylist 上海
4
127.0.0.1:6379> LRANGE mylist 0 -1
上海
18
alvin
127.0.0.1:6379>

3)從左邊插入元素

從右邊插入元素,從右邊依次追加進佇列,先進先出,後進後出。
RPUSH key element [element ...]
 
127.0.0.1:6379> RPUSH mylist linux
5
127.0.0.1:6379> RPUSH mylist python
6
127.0.0.1:6379> LRANGE mylist 0 -1
上海
18
alvin
上海市
linux
python

4) list存在時才會從左邊依次追加元素

#與sting型別中的nx類似,只有當list存在時才會從左邊依次追加元素。

LPUSHX key element [element ...]

127.0.0.1:6379> LPUSHX mylist Shanghai
7
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
18
alvin
上海市
linux
python
127.0.0.1:6379> LPUSHX testlist Shanghai
0
127.0.0.1:6379> LRANGE testlist 0 -1

127.0.0.1:6379>

5)當list存在時才會從右邊依次追加元素

#與lpushx類似,只有當list存在時才會從右邊依次追加元素。
RPUSHX key element [element ...]

127.0.0.1:6379> RPUSHX mylist QingPu
8
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
18
alvin
上海市
linux
python
QingPu
127.0.0.1:6379> RPUSHX testlist QingPu
0
127.0.0.1:6379> LRANGE testlist 0 -1

127.0.0.1:6379>

6) 從list中指定的元素的前/後 插入一個新元素

LINSERT key BEFORE|AFTER pivot element

127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
18
alvin
上海市
linux
python
QingPu

# 在某個KEY之前插入某個值
127.0.0.1:6379> LINSERT mylist before 18 17
9
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
18
alvin
上海市
linux
python
QingPu

# 在某個值後面新增一個值
127.0.0.1:6379> LINSERT mylist after 18 16
10
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
18
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379>

7) 刪除資料

#1.從列表左側開始移除
LREM key count element

127.0.0.1:6379> LINSERT mylist after 18 16
14
127.0.0.1:6379> LINSERT mylist after 18 16
15
127.0.0.1:6379> LINSERT mylist after 18 16
16
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
17
17
17
18
16
16
16
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379> LREM mylist 2 16
2
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
17
17
17
18
16
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379>

8) 修改資料

#1.修改元素內容
LSET key index element

127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
17
17
17
17
18
16
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379> LSET mylist 2 19
OK
127.0.0.1:6379> LRANGE mylist 0 -1
Shanghai
上海
19
17
17
17
18
16
16
alvin
上海市
linux
python
QingPu
127.0.0.1:6379>

#2.擷取為從下標start到下標stop閉區間的列表
將原列表擷取為從下標start到下標stop閉區間的列表,即原列表變為一個第start+1個到第stop+1個元素的列表。
LTRIM key start stop

127.0.0.1:6379> LTRIM mylist 2 8
OK
127.0.0.1:6379> LRANGE mylist 0 -1
19
17
17
17
18
16
16
127.0.0.1:6379>

9) 查詢資料

#1.檢視列表中元素的個數
LLEN key

127.0.0.1:6379> LLEN mylist
7
127.0.0.1:6379>

#2.根據起止下標查詢列表元素
LRANGE key start stop
 
lrange key 0 -1 #表示檢視全部元素
lrange key -1 -1 #表示檢視最右邊的元素

#3.根據指定的index下標檢視列表中的元素
LINDEX key index

127.0.0.1:6379> LINDEX mylist 3
17
127.0.0.1:6379>

#4.從左邊消費列表中的元素
從左邊消費列表中的元素,消費完之後從列表中刪除。

LPOP key

127.0.0.1:6379> LRANGE mylist 0 -1
17
17
17
18
16
16
127.0.0.1:6379> LPOP mylist
17
127.0.0.1:6379> LRANGE mylist 0 -1
17
17
18
16
16
127.0.0.1:6379>

#5.從右邊消費列表中的元素
從右邊消費列表中的元素,消費完之後從列表中刪除。
RPOP key

127.0.0.1:6379> LRANGE mylist 0 -1
17
17
18
16
16
127.0.0.1:6379> RPOP mylist
16
127.0.0.1:6379> LRANGE mylist 0 -1
17
17
18
16
127.0.0.1:6379>

#6.消費列表最右邊的元素並返回
消費列表A的最右邊的元素返回,然後追加到列表B的最左邊。
RPOPLPUSH source destination
 
RPOPLPUSH List_A List_B

127.0.0.1:6379> LRANGE mylist 0 -1
17
17
18
16
127.0.0.1:6379> RPOPLPUSH mylist mylist
16
127.0.0.1:6379> LRANGE mylist 0 -1
16
17
17
18
127.0.0.1:6379>

#7.從列表中左側查詢元素
從列表中左側查詢元素,返回列表的key和左側第一個元素,若所有查詢的列表中都沒有元素,則會阻塞等待至設定的timeout秒之後返回空,若在這期間,這些列表新增了元素,則會立刻消費並返回該元素。
BLPOP key [key ...] timeout

127.0.0.1:6379> BLPOP mylist 10
mylist
16
127.0.0.1:6379> BLPOP mylist 10
mylist
17
127.0.0.1:6379> BLPOP mylist 10
mylist
17
127.0.0.1:6379> BLPOP mylist 10
mylist
18
127.0.0.1:6379> BLPOP mylist 10

# 從列表右側開始消費

4.Redis資料結構之無序集合

Redis 的 Set 是 string 型別的無序集合。集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是 O(1)。集合中最大的成員數為 2^32 - 1 (4294967295, 每個集合可儲存40多億個成員)。

1) 檢視幫助命令

#使用Redis命令手冊檢視
127.0.0.1:6379> help @set

2) 增加資料

7.2.1、	給集合內新增成員
給集合內新增成員,若集合不存在則建立集合並新增成員。

SADD key member [member ...]

127.0.0.1:6379> sadd myset 1
1
127.0.0.1:6379> sadd myset 2
1
127.0.0.1:6379> sadd myset 3
1
127.0.0.1:6379> sadd myset 4
1
127.0.0.1:6379> sadd myset 5
1
127.0.0.1:6379> SMEMBERS myset
1
2
3
4
5
127.0.0.1:6379>

3) 刪除資料

#1.從集合中刪除指定的成員
從集合中刪除指定的成員,返回刪除的個數。
SREM key member [member ...]

127.0.0.1:6379> SREM myset 3 4
2
127.0.0.1:6379> SMEMBERS myset
1
2
5
127.0.0.1:6379>

4) 修改資料

#1.移動資料
127.0.0.1:6379> SADD myset1 1 2 3 4 5
5
127.0.0.1:6379> sadd myset2 one two three
3
127.0.0.1:6379> SMOVE myset1 myset2 4
1
127.0.0.1:6379> SMEMBERS myset1
1
2
3
5
127.0.0.1:6379> SMEMBERS myset2
4
three
two
one
127.0.0.1:6379>

5) 檢視資料

#1.檢視集合中所有的成員
SMEMBERS key

127.0.0.1:6379> SMEMBERS myset2
4
three
two
one

#2.返回集合中成員的個數
SCARD key

127.0.0.1:6379> SMEMBERS myset2
4
three
two
one
127.0.0.1:6379> SCARD myset2
4

#3.從集合中隨機返回指定個數的成員

SRANDMEMBER key [count]

127.0.0.1:6379> SRANDMEMBER myset1 2
3
2
127.0.0.1:6379> SRANDMEMBER myset1 2
1
5

#4.判斷物件是否是集合中的成員
SISMEMBER key member

127.0.0.1:6379> SISMEMBER myset1 6
0
127.0.0.1:6379> SISMEMBER myset1 3
1

#5.隨機返回一個成員
從集合中隨機彈出一個成員,返回該成員並從集合中刪除該成員。

SPOP key

127.0.0.1:6379> SPOP myset1
2
127.0.0.1:6379> SPOP myset2
4
127.0.0.1:6379> SPOP myset2
one
127.0.0.1:6379> SPOP myset2
two
127.0.0.1:6379> SPOP myset2 2
three

6) 交集

#1.取多個集合的交集
取多個集合的交集,返回這些集合中共同擁有的成員。

SINTER key [key ...]

127.0.0.1:6379> sadd myseta 1 2 3 4 5
5
127.0.0.1:6379> sadd mysetb 4 5 6 7 8
5
127.0.0.1:6379> sadd mysetc 5 6 7 8 9
5
127.0.0.1:6379> SINTER myseta mysetb mysetc
5

#2.將多個集合的交集的結果儲存為一個新的集合
將多個集合的交集的結果儲存為一個新的集合destination  ,返回新集合的成員個數。
SINTERSTORE destination key [key ...]

127.0.0.1:6379> SINTERSTORE mysetc mysetb myseta
4
127.0.0.1:6379> SMEMBERS mysetc
5
6
7
8
127.0.0.1:6379> SMEMBERS mysetb
4
5
6
7
8
127.0.0.1:6379> SMEMBERS myseta
5
6
7
8
127.0.0.1:6379>

7) 並集

#1.取多個集合的並集
取多個集合的並集,相同的成員會被去重。
SUNION key [key ...]

127.0.0.1:6379> SADD myset_a 1 2 3 4 5
5
127.0.0.1:6379> sadd myset_b 3 4 5 6 7
5
127.0.0.1:6379> SUNION myset_a myset_b
1
2
3
4
5
6
7
127.0.0.1:6379>

#2.將多個集合的並集的結果儲存為一個新的集合
SUNIONSTORE destination key [key ...]

127.0.0.1:6379> SUNIONSTORE new_myset myset_a myset_b
7
127.0.0.1:6379> SMEMBERS new_myset
1
2
3
4
5
6
7
127.0.0.1:6379>

8) 差集

#1.取多個集合的差集
取多個集合的差集,以最左邊的為主集合,返回左集合中有而其他集合沒有的成員。
127.0.0.1:6379> SDIFF myset_a myset_b
1
2
127.0.0.1:6379> SMEMBERS myset_a
1
2
3
4
5
127.0.0.1:6379> SMEMBERS myset_b
3
4
5
6
7

9) 將多個集合的差集的結果儲存為一個新的集合

#將多個集合的差集的結果儲存為一個新的集合 ,返回新集合的成員個數 。
SDIFFSTORE destination key [key ...]

127.0.0.1:6379> SDIFFSTORE myset_sdiff myset_a myset_b
2
127.0.0.1:6379> SMEMBERS myset_sdiff
1
2
127.0.0.1:6379>

5.Redis資料結構之有序集合

	Redis 有序集合和集合一樣也是string型別元素的集合,且不允許重複的成員。不同的是每個元素都會關聯一個double型別的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。有序集合的成員是唯一的,但分數(score)卻可以重複。集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是O(1)。 集合中最大的成員數為 2^32 - 1 (4294967295, 每個集合可儲存40多億個成員)。

1) 檢視命令幫助

127.0.0.1:6379> help @sorted_set

2) 增加資料

往有序集合中新增成員,需要指定該成員的分數,分數可以是整形或浮點型,當分數相同時候,索引下標按照字典排序。

127.0.0.1:6379> ZADD myzset 1 alvin
1
127.0.0.1:6379> ZADD myzset 2 shanghai 3 beijing
2
127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing

3)查詢資料

#1.獲取有序集合的成員數
ZCARD key

127.0.0.1:6379> ZCARD myzset
3
127.0.0.1:6379>

#2.獲取指定分數區間內的成員數
從有序集合內獲取指定分數區間內的成員數。
ZCOUNT key min max

127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
127.0.0.1:6379> ZCOUNT myzset 1 2
2
127.0.0.1:6379>

#3.字典排序
根據字典排序返回min ,max之間的資料量.
ZLEXCOUNT key min max

127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
127.0.0.1:6379> ZLEXCOUNT myzset [al [zzz
3
127.0.0.1:6379>

#4.獲取成員的分數值
返回有序集中,成員的分數值,不存在的成員返回空。

ZSCORE key member

127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
127.0.0.1:6379> ZSCORE myzset shanghai
2

#5.	127.0.0.1:6379> ZSCAN myzset 0 match "sh*"
0
shanghai
2
127.0.0.1:6379> ZSCAN myzset 0 match "al*"
0
alvin
1

5)刪除資料

#1.移除指定的成員
ZREM key member [member ...]

127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
shanghai
beijing
127.0.0.1:6379> ZREM myzset shanghai
1
127.0.0.1:6379> ZRANGE myzset 0 -1
alvin
beijing
127.0.0.1:6379>

6.Redis基礎命令之常用命令

1) 檢視所有key

127.0.0.1:6379> KEYS *

2) 檢視key的型別

127.0.0.1:6379> TYPE myset1
set
127.0.0.1:6379> TYPE a
string

3) 隨機返回一個key

127.0.0.1:6379> RANDOMKEY
myset_sdiff
127.0.0.1:6379> RANDOMKEY
new_myset
127.0.0.1:6379> RANDOMKEY
myset

4) 刪除key

返回刪除狀態1/0,True/False。
del key [key2 key3 key4...]

5) 判斷一個key是否存在

返回狀態1/0,True/False,當傳入多個key時返回or的結果,即只要有一個存在就返回True。
exists key [key ...]

6) 重新命名一個key

127.0.0.1:6379> RENAME myset mysets
OK
127.0.0.1:6379>

7) 檢視key的剩餘生存時間

#1.以秒為單位
ttl key
127.0.0.1:6379> ttl mysets
-1	# -1代表永不過期

#2.以毫秒為單位
Pttl key
127.0.0.1:6379> PTTL a
-1	# -1代表永不過期