溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

redis4.0入門小結(jié)

發(fā)布時(shí)間:2020-10-19 04:58:48 來(lái)源:腳本之家 閱讀:157 作者:W-D 欄目:數(shù)據(jù)庫(kù)

前言

redis作為nosql家族中非常熱門的一員,也是被大型互聯(lián)網(wǎng)公司所青睞,無(wú)論你是開發(fā)、測(cè)試或者運(yùn)維,學(xué)習(xí)掌握它總會(huì)為你的職業(yè)生涯增色添彩。

當(dāng)然,你或多或少已經(jīng)了解redis,但是你是否了解其中的某些細(xì)節(jié),本片文章將詳細(xì)介紹redis基礎(chǔ),后續(xù)也會(huì)介紹其高級(jí)部分如、持久化、復(fù)制、集群等內(nèi)容,希望對(duì)你有所幫助。

自redis3.0發(fā)布已經(jīng)3年了,redis目前官方提供的redis穩(wěn)定版本是4.0,以下示例均在4.0版本上進(jìn)行。

一、redis簡(jiǎn)介

概述

redis(REmote DIctionary Server)是一個(gè)由Salvatore Sanfilippo寫key-value存儲(chǔ)系統(tǒng),它由C語(yǔ)言編寫、遵守BSD協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value類型的數(shù)據(jù)庫(kù),并提供多種語(yǔ)言的API。和Memcached類似,它支持存儲(chǔ)的value類型相對(duì)更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會(huì)周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)了master-slave(主從)同步,redis在3.0版本推出集群模式。

特點(diǎn)、優(yōu)勢(shì)

  • k、v鍵值存儲(chǔ)以及數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)(如列表、字典)
  • 所有數(shù)據(jù)(包括數(shù)據(jù)的存儲(chǔ))操作均在內(nèi)存中完成
  • 單線程服務(wù)(這意味著會(huì)有較多的阻塞情況),采用epoll模型進(jìn)行請(qǐng)求響應(yīng),對(duì)比nginx
  • 支持主從復(fù)制模式,更提供高可用主從復(fù)制模式(哨兵)
  • 去中心化分布式集群
  • 豐富的編程接口支持,如Python、Golang、Java、php、Ruby、Lua、Node.js
  • 功能豐富,除了支持多種數(shù)據(jù)結(jié)構(gòu)之外,還支持事務(wù)、發(fā)布/訂閱、消息隊(duì)列等功能
  • 支持?jǐn)?shù)據(jù)持久化(AOF、RDB)

對(duì)比memcache

  • memcache是一個(gè)分布式的內(nèi)存對(duì)象緩存系統(tǒng),并不提供持久存儲(chǔ)功能,而redis擁有持久化功能
  • memcache數(shù)據(jù)存儲(chǔ)基于LRU(簡(jiǎn)單說(shuō):最近、最少使用key會(huì)被剔除),而redis則可以永久保存(服務(wù)一直運(yùn)行情況下)
  • memcache是多線程的(這是memcache優(yōu)勢(shì)之一),也就意味著阻塞情況少,而redis是單線程的,阻塞情況相對(duì)較多
  • 兩者性能上相差不大
  • memcache只支持簡(jiǎn)單的k、v數(shù)據(jù)存儲(chǔ),而redis支持多種數(shù)據(jù)格式存儲(chǔ)。
  • memcache是多線程、非阻塞IO復(fù)用網(wǎng)絡(luò)模型,而redis是單線程IO復(fù)用模型

二、開始

源碼部署

yum install gcc -y #安裝C依賴
wget http://download.redis.io/redis-stable.tar.gz #下載穩(wěn)定版本
tar zxvf redis-stable.tar.gz #解壓
cd redis-stable
make PREFIX=/opt/app/redis install  #指定目錄編譯,也可以不用指定
make install
mkdir /etc/redis  #建立配置目錄
cp redis.conf /etc/redis/6379.conf # 拷貝配置文件
cp utils/redis_init_script /etc/init.d/redis #拷貝init啟動(dòng)腳本針對(duì)6.X系統(tǒng)
chmod a+x /etc/init.d/redis #添加執(zhí)行權(quán)限
vi /etc/redis/6379.conf #修改配置文件: 
bind 0.0.0.0   #監(jiān)聽地址
maxmemory 4294967296  #限制最大內(nèi)存(4G):
daemonize yes  #后臺(tái)運(yùn)行

####啟動(dòng)與停止
/etc/init.d/redis start
/etc/init.d/redis stop

查看是否成功安裝

#執(zhí)行客戶端工具
redis-cli 
#輸入命令info
127.0.0.1:6379> info
# Server
redis_version:4.0.10
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:cf83e9c690dbed33
redis_mode:standalone
os:Linux 2.6.32-642.el6.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll

二進(jìn)制文件說(shuō)明

redis安裝完成后會(huì)有以下可執(zhí)行文件(window下是exe文件)生成,下面是各個(gè)文件的作用。

redis-server      #Redis服務(wù)器和Sentinel服務(wù)器,啟動(dòng)時(shí)候可使用--sentinel指定為哨兵
redis-cli       #Redis命令行客戶端 
redis-benchmark    #Redis性能測(cè)試工具 
redis-check-aof   #AOF文件修復(fù)工具 
redis-check-dump   #RDB文件檢測(cè)工具 
redis-sentinel    #Sentinel服務(wù)器,4.0版本已經(jīng)做了軟鏈接到redis-server

三、配置詳解

redis所有的配置參數(shù)都可以通過(guò)客戶端通過(guò)“CONFIG GET 參數(shù)名” 獲取,參數(shù)名支持通配符,如*代表所有。所得結(jié)果并按照順序分組,第一個(gè)返回結(jié)果是參數(shù)名,第二個(gè)結(jié)果是參數(shù)對(duì)應(yīng)的值。

redis4.0入門小結(jié)

除了查看配置還可以使用CONFIG SET修改配置,寫入配置文件使用CONFIG REWRITE,使用時(shí)是需要注意某些關(guān)于服務(wù)配置參數(shù)慎重修改,如bind。

redis4.0入門小結(jié)

配置參數(shù)以及解釋,需要注意的是,有些配置是4.0.10新增的,有些配置已經(jīng)廢除,如vm相關(guān)配置,和集群相關(guān)配置在集群篇章在進(jìn)行補(bǔ)充。

logfile
#日志文件位置及文件名稱

bind 0.0.0.0
#監(jiān)聽地址,可以有多個(gè) 如bind 0.0.0.0 127.0.0.1

daemonize yes
#yes啟動(dòng)守護(hù)進(jìn)程運(yùn)行,即后臺(tái)運(yùn)行,no表示不啟用

pidfile /var/run/redis.pid 
# 當(dāng)redis在后臺(tái)運(yùn)行的時(shí)候,Redis默認(rèn)會(huì)把pid文件在在/var/run/redis.pid,也可以配置到其他地方。
# 當(dāng)運(yùn)行多個(gè)redis服務(wù)時(shí),需要指定不同的pid文件和端口

port 6379
# 指定redis運(yùn)行的端口,默認(rèn)是6379

unixsocket 
#sock文件位置

unixsocketperm
#sock文件權(quán)限

timeout 0
# 設(shè)置客戶端連接時(shí)的超時(shí)時(shí)間,單位為秒。當(dāng)客戶端在這段時(shí)間內(nèi)沒有發(fā)出任何指令,那么關(guān)閉該連接, 0是關(guān)閉此設(shè)置

loglevel debug
# 指定日志記錄級(jí)別,Redis總共支持四個(gè)級(jí)別:debug、verbose、notice、warning,默認(rèn)為verbose

logfile ""
# 日志文件配置,默認(rèn)值為stdout,標(biāo)準(zhǔn)輸出,若后臺(tái)模式會(huì)輸出到/dev/null

syslog-enabled
# 是否以syslog方式記錄日志,yes開啟no禁用,與該配置相關(guān)配置syslog-ident 和syslog-facility local0 分別是指明syslog的ident和facility

databases 16
#配置可用的數(shù)據(jù)庫(kù)個(gè)數(shù),默認(rèn)值為16,默認(rèn)數(shù)據(jù)庫(kù)為0,數(shù)據(jù)庫(kù)范圍在0-(database-1)之間

always-show-logo yes #4.0以后新增配置
#是否配置日志顯示redis徽標(biāo),yes顯示no不顯示


################################ 快照相關(guān)配置 #################################

save 900 1
save 300 10
save 60 10000
#配置快照(rdb)促發(fā)規(guī)則,格式:save <seconds> <changes>
#save 900 1 900秒內(nèi)至少有1個(gè)key被改變則做一次快照
#save 300 10 300秒內(nèi)至少有300個(gè)key被改變則做一次快照
#save 60 10000 60秒內(nèi)至少有10000個(gè)key被改變則做一次快照

dbfilename dump.rdb
#rdb持久化存儲(chǔ)數(shù)據(jù)庫(kù)文件名,默認(rèn)為dump.rdb

stop-write-on-bgsave-error yes 
#yes代表當(dāng)使用bgsave命令持久化出錯(cuò)時(shí)候停止寫RDB快照文件,no則代表繼續(xù)寫

rdbchecksum yes
#開啟rdb文件校驗(yàn)

dir "/etc"
#數(shù)據(jù)文件存放目錄,rdb快照文件和aof文件都會(huì)存放至該目錄


################################# 復(fù)制相關(guān)配置參數(shù) #################################

slaveof <masterip> <masterport> 
#設(shè)置該數(shù)據(jù)庫(kù)為其他數(shù)據(jù)庫(kù)的從數(shù)據(jù)庫(kù),設(shè)置當(dāng)本機(jī)為slave服務(wù)時(shí),設(shè)置master服務(wù)的IP地址及端口,在Redis啟動(dòng)時(shí),它會(huì)自動(dòng)從master進(jìn)行數(shù)據(jù)同步

masterauth <master-password>
#主從復(fù)制中,設(shè)置連接master服務(wù)器的密碼(前提master啟用了認(rèn)證)

slave-serve-stale-data yes
# 當(dāng)從庫(kù)同主機(jī)失去連接或者復(fù)制正在進(jìn)行,從機(jī)庫(kù)有兩種運(yùn)行方式:
# 1) 如果slave-serve-stale-data設(shè)置為yes(默認(rèn)設(shè)置),從庫(kù)會(huì)繼續(xù)相應(yīng)客戶端的請(qǐng)求
# 2) 如果slave-serve-stale-data是指為no,除了INFO和SLAVOF命令之外的任何請(qǐng)求都會(huì)返回一個(gè)錯(cuò)誤"SYNC with master in progress"

repl-ping-slave-period 10
#從庫(kù)會(huì)按照一個(gè)時(shí)間間隔向主庫(kù)發(fā)送PING命令來(lái)判斷主服務(wù)器是否在線,默認(rèn)是10秒

repl-timeout 60
#設(shè)置主庫(kù)批量數(shù)據(jù)傳輸時(shí)間或者ping回復(fù)時(shí)間間隔超時(shí)時(shí)間,默認(rèn)值是60秒
# 一定要確保repl-timeout大于repl-ping-slave-period

repl-backlog-size 1mb
#設(shè)置復(fù)制積壓大小,只有當(dāng)至少有一個(gè)從庫(kù)連入才會(huì)釋放。

slave-priority 100
#當(dāng)主庫(kù)發(fā)生宕機(jī)時(shí)候,哨兵會(huì)選擇優(yōu)先級(jí)最高的一個(gè)稱為主庫(kù),從庫(kù)優(yōu)先級(jí)配置默認(rèn)100,數(shù)值越小優(yōu)先級(jí)越高

min-slaves-to-write 3
min-slaves-max-lag 10
#設(shè)置某個(gè)時(shí)間斷內(nèi),如果從庫(kù)數(shù)量小于該某個(gè)值則不允許主機(jī)進(jìn)行寫操作,以上參數(shù)表示10秒內(nèi)如果主庫(kù)的從節(jié)點(diǎn)小于3個(gè),則主庫(kù)不接受寫請(qǐng)求,min-slaves-to-write 0代表關(guān)閉此功能。


################################## 安全相關(guān)配置 ###################################

requirepass
#客戶端連接認(rèn)證的密碼,默認(rèn)為空,即不需要密碼,若配置則命令行使用AUTH進(jìn)行認(rèn)證

maxclients 10000
# 設(shè)置同一時(shí)間最大客戶端連接數(shù),4.0默認(rèn)10000,Redis可以同時(shí)打開的客戶端連接數(shù)為Redis進(jìn)程可以打開的最大文件描述符數(shù),
# 如果設(shè)置 maxclients 0,表示不作限制。
# 當(dāng)客戶端連接數(shù)到達(dá)限制時(shí),Redis會(huì)關(guān)閉新的連接并向客戶端返回max number of clients reached錯(cuò)誤信息

maxmemory 4gb
#設(shè)置最大使用的內(nèi)存大小

maxmemory-policy noeviction
#設(shè)置達(dá)到最大內(nèi)存采取的策略:
# volatile-lru -> 利用LRU算法移除設(shè)置過(guò)過(guò)期時(shí)間的key (LRU:最近使用 Least Recently Used )
# allkeys-lru -> 利用LRU算法移除任何key
# volatile-random -> 移除設(shè)置過(guò)過(guò)期時(shí)間的隨機(jī)key
# allkeys->random -> remove a random key, any key
# volatile-ttl -> 移除即將過(guò)期的key(minor TTL)
# 4.0默認(rèn)noeviction代表不刪除任何key,只在寫操作時(shí)候返回錯(cuò)誤。

maxmemory-samples 5
#LRU,LFU等算法樣本設(shè)置,默認(rèn)5個(gè)key


############################## AOF相關(guān)配置###############################

appendonly no
# 設(shè)置AOF持久化,yes開啟,no禁用,開啟后redis會(huì)把所接收到的每一次寫操作請(qǐng)求都追加到appendonly.aof文件中,當(dāng)redis重新啟動(dòng)時(shí),會(huì)從該文件恢復(fù)出之前的狀態(tài)。
# 但是這樣會(huì)造成appendonly.aof文件過(guò)大,所以redis還支持了BGREWRITEAOF指令,對(duì)appendonly.aof 進(jìn)行重寫。

appendfilename "appendonly.aof"
#設(shè)置AOF文件名

appendfsync everysec
# AOF文件寫策略,Redis支持三種同步AOF文件的策略:
# no: 不進(jìn)行同步,交給操作系統(tǒng)去執(zhí)行 ,速度較快
# always: always表示每次有寫操作都調(diào)用fsync方法強(qiáng)制內(nèi)核將該寫操作寫入到文件,速度會(huì)慢, 但是安全,因?yàn)槊看螌懖僮鞫荚贏OF文件中.
# everysec: 表示對(duì)寫操作進(jìn)行累積,每秒同步一次,折中方案.
# 默認(rèn)是"everysec",按照速度和安全折中這是最好的。

no-appendfsync-on-rewrite no
# AOF策略設(shè)置為always或者everysec時(shí),后臺(tái)處理進(jìn)程(后臺(tái)保存或者AOF日志重寫)會(huì)執(zhí)行大量的I/O操作
# 在某些Linux配置中會(huì)阻止過(guò)長(zhǎng)的fsync()請(qǐng)求。注意現(xiàn)在沒有任何修復(fù),即使fsync在另外一個(gè)線程進(jìn)行處理,為了減緩這個(gè)問(wèn)題,可以設(shè)置下面這個(gè)參數(shù)no-appendfsync-on-rewrite

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
#當(dāng)AOF文件增長(zhǎng)到一定大小的時(shí)候Redis能夠調(diào)用BGREWRITEAOF對(duì)日志文件進(jìn)行重寫,它是這樣工作的:Redis會(huì)記住上次進(jìn)行些日志后文件的大小(如果從開機(jī)以來(lái)還沒進(jìn)行過(guò)重寫,那日子大小在開機(jī)的時(shí)候確定)。
#基礎(chǔ)大小會(huì)同現(xiàn)在的大小進(jìn)行比較。如果現(xiàn)在的大小比基礎(chǔ)大小大制定的百分比,重寫功能將啟動(dòng)
# 同時(shí)需要指定一個(gè)最小大小用于AOF重寫,這個(gè)用于阻止即使文件很小但是增長(zhǎng)幅度很大也去重寫AOF文件的情況
# 設(shè)置 percentage 為0就關(guān)閉這個(gè)特性
#auto-aof-rewrite-percentage 代表AOF文件每次重寫文件大小(以百分?jǐn)?shù)代表),100表示百分之百,即當(dāng)文件增加了1倍(100%),則開始重寫AOF文件
#auto-aof-rewrite-min-size 設(shè)置最小重寫文件大小,避免文件小而執(zhí)行太多次的重寫

aof-load-truncated yes
#當(dāng)redis突然運(yùn)行崩潰時(shí),會(huì)出現(xiàn)aof文件被截?cái)嗟那闆r,Redis可以在發(fā)生這種情況時(shí)退出并加載錯(cuò)誤,以下選項(xiàng)控制此行為。
#如果aof-load-truncated設(shè)置為yes,則加載截?cái)嗟腁OF文件,Redis服務(wù)器啟動(dòng)發(fā)出日志以通知用戶該事件。
#否則,如果該選項(xiàng)設(shè)置為no,則服務(wù)器將中止并顯示錯(cuò)誤并停止啟動(dòng)。當(dāng)該選項(xiàng)設(shè)置為no時(shí),用戶需要在重啟之前使用“redis-check-aof”實(shí)用程序修復(fù)AOF文件在進(jìn)行重啟


################################## 慢查詢配置 ###################################


slowlog-log-slower-than 10000
 #Redis Slow Log 記錄超過(guò)特定執(zhí)行時(shí)間的命令。執(zhí)行時(shí)間不包括I/O計(jì)算比如連接客戶端,返回結(jié)果等,只是命令執(zhí)行時(shí)間,可以通過(guò)兩個(gè)參數(shù)設(shè)置slow log:一個(gè)是告訴Redis執(zhí)行超過(guò)多少時(shí)間被記錄的參數(shù)slowlog-log-slower-than(微秒,因此1000000代表一分鐘
#另一個(gè)是slow log 的長(zhǎng)度。當(dāng)一個(gè)新命令被記錄的時(shí)候最早的命令將被從隊(duì)列中移除
 
slowlog-max-len 128
#慢查詢命令記錄隊(duì)列長(zhǎng)度設(shè)置,該隊(duì)列占用內(nèi)存,可以使用SLOWLOG RESET清空隊(duì)列



############################### 高級(jí)配置 ###############################

hash-max-zipmap-entries 512
hash-max-zipmap-value 64
# 當(dāng)hash中包含超過(guò)指定元素個(gè)數(shù)并且最大的元素沒有超過(guò)臨界時(shí),hash將以一種特殊的編碼方式(大大減少內(nèi)存使用)來(lái)存儲(chǔ),這里可以設(shè)置這兩個(gè)臨界值
# Redis Hash對(duì)應(yīng)Value內(nèi)部實(shí)際就是一個(gè)HashMap,實(shí)際這里會(huì)有2種不同實(shí)現(xiàn),
# 這個(gè)Hash的成員比較少時(shí)Redis為了節(jié)省內(nèi)存會(huì)采用類似一維數(shù)組的方式來(lái)緊湊存儲(chǔ),而不會(huì)采用真正的HashMap結(jié)構(gòu),對(duì)應(yīng)的value redisObject的encoding為zipmap,當(dāng)成員數(shù)量增大時(shí)會(huì)自動(dòng)轉(zhuǎn)成真正的HashMap,此時(shí)encoding為ht。

list-max-ziplist-size -2
#Lists也以特殊方式編碼,以節(jié)省大量空間。
#可以指定每個(gè)內(nèi)部列表節(jié)點(diǎn)允許的條目數(shù)
#作為固定的最大大小或最大元素?cái)?shù)。
#對(duì)于固定的最大大小,使用-5到-1表示:
#-5:最大大小:64 Kb < - 不建議用于正常工作負(fù)載
#-4:最大尺寸:32 Kb < - 不推薦
#-3:最大尺寸:16 Kb < - 可能不推薦
#-2:最大尺寸:8 Kb < - 好
#-1:最大尺寸:4 Kb < - 良好
#正數(shù)意味著存儲(chǔ)_exactly_元素?cái)?shù)量
#每個(gè)列表節(jié)點(diǎn)。
#性能最高的選項(xiàng)通常為-2(8 Kb大?。┗?1(4 Kb大?。?
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
# list數(shù)據(jù)類型多少節(jié)點(diǎn)以下會(huì)采用去指針的緊湊存儲(chǔ)格式。
# list數(shù)據(jù)類型節(jié)點(diǎn)值大小小于多少字節(jié)會(huì)采用緊湊存儲(chǔ)格式。

activerehashing yes
# Redis將在每100毫秒時(shí)使用1毫秒的CPU時(shí)間來(lái)對(duì)redis的hash表進(jìn)行重新hash,可以降低內(nèi)存的使用
# 當(dāng)你的使用場(chǎng)景中,有非常嚴(yán)格的實(shí)時(shí)性需要,不能夠接受Redis時(shí)不時(shí)的對(duì)請(qǐng)求有2毫秒的延遲的話,把這項(xiàng)配置為no。
# 如果沒有這么嚴(yán)格的實(shí)時(shí)性要求,可以設(shè)置為yes,以便能夠盡可能快的釋放內(nèi)存

client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
#客戶端輸出緩沖區(qū)限制可用于強(qiáng)制斷開客戶端,由于某種原因,沒有足夠快地從服務(wù)器讀取數(shù)據(jù),常見的原因是Pub / Sub客戶端不能像很快的消費(fèi)一條消息,可以為三種不同類型的客戶端設(shè)置不同的限制:
#normal - >普通客戶端,包括MONITOR客戶端
#subve - >從服務(wù)器客戶端
#pubsub - >客戶端訂閱了至少一個(gè)pubsub通道或模式
#設(shè)置方法:client-output-buffer-limit 軟限制大小 硬限制大小 秒數(shù)
#當(dāng)客戶端達(dá)到硬限制大小則立即斷開連接,當(dāng)客戶端達(dá)到軟限制時(shí)候并且在設(shè)置的秒數(shù)緩沖大小任然超了,則在設(shè)置的秒數(shù)后斷開連接

四、數(shù)據(jù)類型以及相關(guān)操作

通常使用redis不外乎使用其常用的5中數(shù)據(jù)類型:string、list、hash、set、sorted_set,在3.2版本以后新添加geo經(jīng)緯度支持,以下將對(duì)其類型的常用操作做說(shuō)明。

命令使用前言

通大多數(shù)據(jù)庫(kù)一樣,redis所有的命令提供了幫助,可以使用help +命令名稱查看其使用方法,幫助信息中不僅有命令用法,還有命令始于版本信息,分組等。

為了友好的使用,redis還將所有命令都進(jìn)行了分組,同時(shí)使用help+@+組名進(jìn)行查看每個(gè)組中所有命令,以下是所有分組信息。

上面以及介紹如何查看命令使用方法,所以在以下數(shù)據(jù)類型操作時(shí)候,只舉例常用的命令,更多命令參考https://redis.io/commands

注意:redis在3.2版本新增geo數(shù)據(jù)類型。

generic    #一般命令組,對(duì)大多數(shù)類型適用
string    #字符串類型命令組,使用所有字符串類型
list     #列表類型命令組
set      #集合類型命令組
sorted_set  #有序集合命令組
hash     #hash操作命令組
pubsub    #發(fā)布命令組
transactions #事務(wù)操作命令組
connection  #連接相關(guān)命令組
server    #服務(wù)器相關(guān)命令組
scripting   #lua 腳本命令組
hyperloglog  #hyperloglog類型命令組,redis在 2.8.9 版本添加了 HyperLogLog 結(jié)構(gòu)
cluster    #集群相關(guān)命令組
geo      #經(jīng)緯度相關(guān)命令組,適用于3.2.0以后的版本

示例:查看事務(wù)操作所有命令

redis4.0入門小結(jié)

key操作

常用:

DEL key #刪除某個(gè)key
KEYS pattern #查看符合正則的所有key
EXISTS key [key ...] #判斷某個(gè)key是否存在,可支持多個(gè),返回存在的個(gè)數(shù)
EXPIRE key seconds #刷新某個(gè)key過(guò)期時(shí)間
MOVE key db #移動(dòng)key到某個(gè)數(shù)據(jù)庫(kù)

示例:

redis4.0入門小結(jié)

string操作

字符串操作中需要注意的是,redis中的整型也當(dāng)作字符串處理。

常用:

SET key value [EX seconds] [PX milliseconds] [NX|XX] #設(shè)置key為指定的字符串值。
#參數(shù):
#EX seconds – 設(shè)置鍵key的過(guò)期時(shí)間,單位時(shí)秒
#PX milliseconds – 設(shè)置鍵key的過(guò)期時(shí)間,單位時(shí)毫秒
#NX – 只有鍵key不存在的時(shí)候才會(huì)設(shè)置key的值
#XX – 只有鍵key存在的時(shí)候才會(huì)設(shè)置key的值

APPEND key value #如果 key 已經(jīng)存在,并且值為字符串,那么這個(gè)命令會(huì)把 value 追加到原來(lái)值(value)的結(jié)尾。 如果 key 不存在,那么它將首先創(chuàng)建一個(gè)空字符串的key,再執(zhí)行追加操作,這種情況 APPEND 將類似于 SET 操作。

GET key #獲取key值,不存在則返回nil

GETRANGE key start end #獲取指定key值的索引開始位置和結(jié)束位置所對(duì)應(yīng)的值,索引從0開始

GETSET key value #設(shè)置新的key值,并獲取設(shè)置之前的值,如果key不存在則設(shè)置,并返回nil

MGET key [key ...]  #批量獲取key的值

MSET key value [key value ...] #批量設(shè)置key的值

DECR key #數(shù)字類型的key自減操作,key類型不是數(shù)字則報(bào)錯(cuò)

INCR key #數(shù)字類型key 自加操作,與DECR相反

DECRBY key decrement #數(shù)字類型key指定減少數(shù)值

INCRBY key increment  #數(shù)字類型key指定增加數(shù)值,與DECRBY相反

STRLEN key #獲取key長(zhǎng)度

示例:

redis4.0入門小結(jié)

list操作

列表中的元素索引從0開始,倒數(shù)的元素可以用“-”+倒數(shù)位置表示,如-2,代表倒數(shù)第二個(gè)元素,-1則代表最后一個(gè)元素。

Redis列表是簡(jiǎn)單的字符串列表,按照插入順序排序。你可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊。

一個(gè)列表最多可以包含 232- 1 個(gè)元素 (4294967295, 每個(gè)列表超過(guò)40億個(gè)元素)。

常用:

LPUSH key value [value ...] #從列表左邊放入一個(gè)或者多個(gè)元素

LPUSHX key value #當(dāng)列表存在時(shí),從左邊放入一個(gè)元素

RPUSH key value [value ...] #從列表右邊放入一個(gè)或者多個(gè)元素

RPUSHX key value #當(dāng)列表存在時(shí),從右邊放入一個(gè)元素

LSET key index value #根據(jù)索引設(shè)置列表中元素的值,當(dāng)list不存在是報(bào)錯(cuò)

LINDEX key index #根據(jù)列表索引獲取元素值,索引從0開始

LINSERT key BEFORE|AFTER pivot value #在列表中,基于某個(gè)基準(zhǔn)點(diǎn)插入值,pivot代表基準(zhǔn)點(diǎn)

LLEN key #獲取列表長(zhǎng)度

LRANGE key start stop #根據(jù)索引獲取列表中的元素,列表索引最后一個(gè)可以使用-1

LREM key count value #從存于 key 的列表里移除前 count 次出現(xiàn)的值為 value 的元素
#count > 0: 從頭往尾移除值為 value 的元素
#count < 0: 從尾往頭移除值為 value 的元素
#count = 0: 移除所有值為 value 的元素

LPOP key #從列表左邊刪除一個(gè)元素

RPOP key #從列表右邊刪除一個(gè)元素

RPOPLPUSH source destination #刪除source列表中的刪除最后一個(gè)元素將其追加到destination列表

LTRIM key start stop #根據(jù)索引start和stop保留列表元素

示例:

redis4.0入門小結(jié)

hash操作

hash操作所有命令都以H開頭。

Redis hash 是一個(gè)string類型的field和value的映射表,hash特別適合用于存儲(chǔ)對(duì)象。

Redis 中每個(gè) hash 可以存儲(chǔ) 232- 1 鍵值對(duì)(40多億)。

常用:

HDEL key field [field ...] #刪除hash表中一個(gè)或多個(gè)字段

HEXISTS key field #判斷hash表中字段是否存在

HGET key field #獲取hash表中字段的值

HGETALL key #獲取hash表中所有字段

HSET key field value # 設(shè)置hash表中字段的值

HSETNX key field value #只有當(dāng)字段不存在時(shí)候才設(shè)置hash表中字段值,

HLEN key #獲取hash表中字段個(gè)數(shù)

HVALS key #獲取hash表中所有字段的值

HKEYS key #獲取hash表中所有的字段

HSTRLEN key field #獲取hash表中指定字段的值的長(zhǎng)度

HMSET key field value [field value ...] #批量設(shè)置hash表中字段的值

HMGET key field [field ...] #批量獲取hash表中字段的值

示例:

redis4.0入門小結(jié)

集合set操作

Redis 的 Set 是 String 類型的無(wú)序集合。集合成員是唯一的,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)。

Redis 中集合是通過(guò)哈希表實(shí)現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是 O(1)。

集合中最大的成員數(shù)為 232 - 1(4294967295, 每個(gè)集合可存儲(chǔ)40多億個(gè)成員)。

常用:

SADD key member [member ...] #添加一個(gè)或多個(gè)元素到集合中

SREM key member [member ...] #刪除一個(gè)或多個(gè)集合中的元素

SCARD key #獲取集合中元素?cái)?shù)量

SMEMBERS key #返回集合中所有的元素

SINTER key [key ...] #獲取兩個(gè)或兩個(gè)以上集合的交集

SUNION key [key ...] #獲取兩個(gè)或兩個(gè)以上集合的并集

SDIFF key [key ...]   #獲取兩個(gè)或者兩個(gè)以上集合的差集

SISMEMBER key member #判斷元素是否是在指定集合中

SMOVE source destination member #移動(dòng)一個(gè)集合中的元素到另一個(gè)集合

SPOP key [count] #移除count個(gè)集合中元素,count可選參數(shù),默認(rèn)為1,即移除一個(gè)

有序集合操作

Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復(fù)的成員。

不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)。redis正是通過(guò)分?jǐn)?shù)來(lái)為集合中的成員進(jìn)行從小到大的排序。

有序集合的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)。

集合是通過(guò)哈希表實(shí)現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是O(1)。 集合中最大的成員數(shù)為 232 - 1(4294967295, 每個(gè)集合可存儲(chǔ)40多億個(gè)成員)。

常用:

ZADD key [NX|XX] [CH] [INCR] score member [score member ...] #向一個(gè)有序集合添加成員(元素)
#參數(shù):
#XX: 僅僅更新存在的成員,不添加新成員。
#NX: 不更新存在的成員。只添加新成員。
#CH: 修改返回值為發(fā)生變化的成員總數(shù),原始是返回新添加成員的總數(shù) (CH 是 changed 的意思)。更改的元素是新添加的成員,已經(jīng)存在的成員更新分?jǐn)?shù)。 所以在命令中指定的成員有相同的分?jǐn)?shù)將不被計(jì)算在內(nèi)。注:在通常情況下,ZADD返回值只計(jì)算新添加成員的數(shù)量。
#INCR: 當(dāng)ZADD指定這個(gè)選項(xiàng)時(shí),成員的操作就等同ZINCRBY命令,對(duì)成員的分?jǐn)?shù)進(jìn)行遞增操作。

ZCARD key #獲取有序集合中元素個(gè)數(shù)

ZCOUNT key min max #指定分?jǐn)?shù)范圍的元素個(gè)數(shù)

ZINCRBY key increment member #為有序集的元素的score值加上增加指定的increment

ZRANGE key start stop [WITHSCORES] #根據(jù)有序集合中分?jǐn)?shù)區(qū)間獲取集合中的元素

ZRANGE key start stop [WITHSCORES] #獲取有序集合中元素的排名

ZREM key member [member ...] #刪除有序集合中一個(gè)或多個(gè)元素

ZSCORE key member #設(shè)置元素在集合中的分?jǐn)?shù)

GEO類型操作

Redis的GEO是 3.2 版本的新特性,對(duì)GEO(地理位置)的支持。這個(gè)功能可以將用戶給定的地理位置信息儲(chǔ)存起來(lái), 并對(duì)這些信息進(jìn)行操作。

geo類型命令不多,總共6個(gè)所以這里全部列舉出來(lái)了。

GEOADD key longitude latitude member [longitude latitude member ...] #將指定的地理空間位置(緯度、經(jīng)度、名稱)添加到指定的key中

GEODIST key member1 member2 [unit] #返回兩個(gè)給定位置之間的距離。如果兩個(gè)位置之間的其中一個(gè)不存在, 那么命令返回空值。指定單位的參數(shù) unit 必須是以下單位的其中一個(gè):

#m 表示單位為米
#km 表示單位為千米
#mi 表示單位為英里
#ft 表示單位為英尺

GEOPOS key member [member ...] #從key里返回所有給定位置元素的位置(經(jīng)度和緯度)

GEOHASH key member [member ...] #返回一個(gè)或多個(gè)位置元素的 Geohash 表示。通常使用表示位置的元素使用不同的技術(shù),使用Geohash位置52點(diǎn)整數(shù)編碼。由于編碼和解碼過(guò)程中所使用的初始最小和最大坐標(biāo)不同,編碼的編碼也不同于標(biāo)準(zhǔn)。此命令返回一個(gè)標(biāo)準(zhǔn)的Geohash

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] 
#以給定的經(jīng)緯度為中心, 返回鍵包含的位置元素當(dāng)中, 與中心的距離不超過(guò)給定最大距離的所有位置元素。

#范圍可以使用以下其中一個(gè)單位:

#m 表示單位為米。
#km 表示單位為千米。
#mi 表示單位為英里。
#ft 表示單位為英尺。
#在給定以下可選項(xiàng)時(shí), 命令會(huì)返回額外的信息:

#WITHDIST: 在返回位置元素的同時(shí), 將位置元素與中心之間的距離也一并返回。 距離的單位和用戶給定的范圍單位保持一致。
#WITHCOORD: 將位置元素的經(jīng)度和維度也一并返回。
#WITHHASH: 以 52 位有符號(hào)整數(shù)的形式, 返回位置元素經(jīng)過(guò)原始 geohash 編碼的有序集合分值。 這個(gè)選項(xiàng)主要用于底層應(yīng)用或者調(diào)試, 實(shí)際中的作用并不大。
#命令默認(rèn)返回未排序的位置元素。 通過(guò)以下兩個(gè)參數(shù), 用戶可以指定被返回位置元素的排序方式:

#ASC: 根據(jù)中心的位置, 按照從近到遠(yuǎn)的方式返回位置元素。
#DESC: 根據(jù)中心的位置, 按照從遠(yuǎn)到近的方式返回位置元素。
#在默認(rèn)情況下, GEORADIUS 命令會(huì)返回所有匹配的位置元素。 雖然用戶可以使用 COUNT <count> 選項(xiàng)去獲取前 N 個(gè)匹配元素, 但是因?yàn)槊钤趦?nèi)部可能會(huì)需要對(duì)所有被匹配的元素進(jìn)行處理, 所以在對(duì)一個(gè)非常大的區(qū)域進(jìn)行搜索時(shí), 即使只使用 COUNT 選項(xiàng)去獲取少量元素, 命令的執(zhí)行速度也可能會(huì)非常慢。 但是從另一方面來(lái)說(shuō), 使用 COUNT 選項(xiàng)去減少需要返回的元素?cái)?shù)量, 對(duì)于減少帶寬來(lái)說(shuō)仍然是非常有用的。

#返回值:
 #在沒有給定任何 WITH 選項(xiàng)的情況下, 命令只會(huì)返回一個(gè)像 [“New York”,”Milan”,”Paris”] 這樣的線性(linear)列表。
 #在指定了 WITHCOORD 、 WITHDIST 、 WITHHASH 等選項(xiàng)的情況下, 命令返回一個(gè)二層嵌套數(shù)組, 內(nèi)層的每個(gè)子數(shù)組就表示一個(gè)元素

 #在返回嵌套數(shù)組時(shí), 子數(shù)組的第一個(gè)元素總是位置元素的名字。 至于額外的信息, 則會(huì)作為子數(shù)組的后續(xù)元素, 按照以下順序被返回:
  #以浮點(diǎn)數(shù)格式返回的中心與位置元素之間的距離, 單位與用戶指定范圍時(shí)的單位一致。
  #geohash 整數(shù)。
  #由兩個(gè)元素組成的坐標(biāo),分別為經(jīng)度和緯度。

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
#這個(gè)命令和 GEORADIUS 命令一樣, 都可以找出位于指定范圍內(nèi)的元素, 但是 GEORADIUSBYMEMBER 的中心點(diǎn)是由給定的位置元素決定的。

操作示例:

redis4.0入門小結(jié)

五、發(fā)布訂閱

Redis 發(fā)布訂閱(pub/sub)是一種消息通信模式:發(fā)送者(pub)發(fā)送消息,訂閱者(sub)接收消息。

Redis 客戶端可以訂閱任意數(shù)量的頻道。

下圖代表其發(fā)布訂閱之間的關(guān)系

redis4.0入門小結(jié)

運(yùn)作原理

每個(gè)Redis 服務(wù)器進(jìn)程都維持著一個(gè)表示服務(wù)器狀態(tài)的 redis.h/redisServer結(jié)構(gòu), 結(jié)構(gòu)的pubsub_channels 屬性是一個(gè)字典, 這個(gè)字典就用于保存訂閱頻道的信息:

struct redisServer {
  // ...
  dict *pubsub_channels;
  // ...
};

其中,字典的鍵為正在被訂閱的頻道, 而字典的值則是一個(gè)鏈表, 鏈表中保存了所有訂閱這個(gè)頻道的客戶端。
比如說(shuō),在下圖展示的這個(gè)pubsub_channels示例中,client1 、 client2 和 client3 就訂閱了 channel1 , 而client3也同時(shí)訂閱了channel2。

當(dāng)客戶端調(diào)用SUBSCRIBE命令時(shí), 程序就將客戶端和要訂閱的頻道在pubsub_channels字典中關(guān)聯(lián)起來(lái)。

redis4.0入門小結(jié)

SUBSCRIBE命令的行為可以用偽代碼表示如下:

def SUBSCRIBE(client, channels):

  // 遍歷所有輸入頻道
  for channel in channels:

    // 將客戶端添加到鏈表的末尾
    redisServer.pubsub_channels[channel].append(client)

通過(guò)pubsub_channels字典, 程序只要檢查某個(gè)頻道是否為字典的鍵, 就可以知道該頻道是否正在被客戶端訂閱; 只要取出某個(gè)鍵的值, 就可以得到所有訂閱該頻道的客戶端的信息。

了解了pubsub_channels字典的結(jié)構(gòu)之后, 解釋PUBLISH命令的實(shí)現(xiàn)就非常簡(jiǎn)單了: 當(dāng)調(diào)用PUBLISH channel message命令, 程序首先根據(jù)channel定位到字典的鍵, 然后將信息發(fā)送給字典值鏈表中的所有客戶端。

訂閱模式

redis的發(fā)布訂閱不僅僅提供簡(jiǎn)單的訂閱頻道,還提供模式匹配訂閱。模式訂閱使用命令PSUBSCRIBE實(shí)現(xiàn)。

redisServer.pubsub_patterns屬性是一個(gè)鏈表,鏈表中保存著所有和模式相關(guān)的信息:

struct redisServer {
  // ...
  list *pubsub_patterns;
  // ...
};

鏈表中的每個(gè)節(jié)點(diǎn)都包含一個(gè)redis.h/pubsubPattern結(jié)構(gòu):

typedef struct pubsubPattern {
  redisClient *client;
  robj *pattern;
} pubsubPattern;

client 屬性保存著訂閱模式的客戶端,而 pattern 屬性則保存著被訂閱的模式。

每當(dāng)調(diào)用 PSUBSCRIBE命令訂閱一個(gè)模式時(shí), 程序就創(chuàng)建一個(gè)包含客戶端信息和被訂閱模式的pubsubPattern結(jié)構(gòu), 并將該結(jié)構(gòu)添加到redisServer.pubsub_patterns鏈表中。

作為例子,下圖展示了一個(gè)包含兩個(gè)模式的 pubsub_patterns 鏈表, 其中 client123 和 client256 都正在訂閱 tweet.shop.* 模式:

redis4.0入門小結(jié)

通過(guò)遍歷整個(gè)pubsub_patterns鏈表,程序可以檢查所有正在被訂閱的模式,以及訂閱這些模式的客戶端。

當(dāng)執(zhí)行PUBLISH進(jìn)行命令向channel命令發(fā)送消息時(shí),PUBLISH除了將message 發(fā)送到所有訂閱channel的客戶端之外, 它還會(huì)將channel和pubsub_patterns中的模式進(jìn)行對(duì)比, 如果channel和某個(gè)模式匹配的話, 那么也將message 發(fā)送到訂閱那個(gè)模式的客戶端,例如一個(gè)客戶端訂閱了aa.bb.*頻道,那么他會(huì)收到來(lái)自所有aa.bb開頭的所有頻道消息。

相關(guān)命令

PSUBSCRIBE pattern [pattern ...] #使用模式訂閱一個(gè)或多個(gè)符合給定模式的頻道

PUNSUBSCRIBE [pattern [pattern ...]] #退訂所有給定模式的頻道

SUBSCRIBE channel [channel ...]  #訂閱給定的一個(gè)或多個(gè)頻道的信息

UNSUBSCRIBE [channel [channel ...]]  #指退訂給定的頻道

PUBSUB subcommand [argument [argument ...]] #查看訂閱與發(fā)布系統(tǒng)狀態(tài)

PUBLISH channel message  #將信息發(fā)送到指定的頻道

實(shí)踐

在以下示例中,將分別用SUBSCRIBE命令訂閱aa.bb和使用PSUBSCRIBE模式訂閱頻道aa.bb*。

SUBSCRIBE訂閱:

redis4.0入門小結(jié)

PSUBSCRIBE訂閱:

redis4.0入門小結(jié)

此時(shí)我們使用PUBSH向aa.bb發(fā)送消息,返回接受到的頻道數(shù),兩個(gè)訂閱者都能收到消息。

redis4.0入門小結(jié)

訂閱者1:

redis4.0入門小結(jié)

模式訂閱者:

redis4.0入門小結(jié)

小結(jié)

  • 訂閱信息由服務(wù)器進(jìn)程維持的redisServer.pubsub_channels字典保存,字典的鍵為被訂閱的頻道,字典的值為訂閱頻道的所有客戶端。
  • 當(dāng)有新消息發(fā)送到頻道時(shí),程序遍歷頻道(鍵)所對(duì)應(yīng)的(值)所有客戶端,然后將消息發(fā)送到所有訂閱頻道的客戶端上。
  • 訂閱模式的信息由服務(wù)器進(jìn)程維持的redisServer.pubsub_patterns鏈表保存,鏈表的每個(gè)節(jié)點(diǎn)都保存著一個(gè)pubsubPattern結(jié)構(gòu),結(jié)構(gòu)中保存著被訂閱的模式,以及訂閱該模式的客戶端。程序通過(guò)遍歷鏈表來(lái)查找某個(gè)頻道是否和某個(gè)模式匹配。
  • 當(dāng)有新消息發(fā)送到頻道時(shí),除了訂閱頻道的客戶端會(huì)收到消息之外,所有訂閱了匹配頻道的模式的客戶端,也同樣會(huì)收到消息。
  • 退訂頻道和退訂模式分別是訂閱頻道和訂閱模式的反操作。

六、事務(wù)

所謂事務(wù)應(yīng)具有以下特效:原子性(Atomicity), 一致性(Consistency),隔離性(Isolation),持久性(Durability),簡(jiǎn)稱ACID,但redis所提供的事務(wù)比較簡(jiǎn)單,它通過(guò)MULTI、EXEC、DISCARD和WATCH等命令實(shí)現(xiàn)事務(wù)。

而Redis只支持簡(jiǎn)單的事務(wù),將執(zhí)行命令放入隊(duì)列緩存,當(dāng)程序中有異?;蛎畛鲥e(cuò),執(zhí)行DISCARD清空緩存隊(duì)列不執(zhí)行隊(duì)列中命令,其事務(wù)過(guò)程有以下特點(diǎn):

  • 事務(wù)是一個(gè)單獨(dú)的隔離操作:事務(wù)中的所有命令都會(huì)序列化、按順序地執(zhí)行。事務(wù)在執(zhí)行的過(guò)程中,不會(huì)被其他客戶端發(fā)送來(lái)的命令請(qǐng)求所打斷。
  • 事務(wù)是一個(gè)泛原子操作(這里我以泛原子稱呼,在某些情況redis的事務(wù)不是原子性的,后續(xù)會(huì)說(shuō)明):事務(wù)中的命令要么全部被執(zhí)行,要么全部都不執(zhí)行。

EXEC命令負(fù)責(zé)觸發(fā)并執(zhí)行事務(wù)中的所有命令:

  • 如果客戶端在使用MULTI開啟了一個(gè)事務(wù)之后,卻因?yàn)閿嗑€而沒有成功執(zhí)行EXEC,那么事務(wù)中的所有命令都不會(huì)被執(zhí)行。
  • 另一方面,如果客戶端成功在開啟事務(wù)之后執(zhí)行EXEC,那么事務(wù)中的所有命令都會(huì)被執(zhí)行。

特別說(shuō)明文中的泛原子操作:

  • redis在開啟事務(wù)以后,若執(zhí)行命令具有顯示的錯(cuò)誤或者客戶端中斷則此次事務(wù)在執(zhí)行EXEC命令時(shí)會(huì)調(diào)用DISCARD清空緩存隊(duì)列不執(zhí)行隊(duì)列中的所有任務(wù),此時(shí)是原子性的。
  • 當(dāng)執(zhí)行命令過(guò)程中,命令沒有顯示的報(bào)錯(cuò)(例如LSET操作設(shè)置一個(gè)不存在的list),而是在EXEC調(diào)用時(shí)候某個(gè)命令出錯(cuò),那么在這之前已經(jīng)執(zhí)行的命令將不會(huì)回滾,所以嚴(yán)格說(shuō)來(lái),redis并不支持原子性。

涉及命令

MULTI #用于標(biāo)記事務(wù)塊的開始。Redis會(huì)將后續(xù)的命令逐個(gè)放入隊(duì)列中,然后才能使用EXEC命令執(zhí)行緩存隊(duì)列中的命令。

EXEC #執(zhí)行緩存隊(duì)列中的命令

DISCARD #清除所有先前在一個(gè)事務(wù)中放入隊(duì)列的命令,然后恢復(fù)正常的連接狀態(tài),如果使用了WATCH命令,那么DISCARD命令就會(huì)將當(dāng)前連接監(jiān)控的所有鍵取消監(jiān)控。

WATCH key [key ...]  #當(dāng)某個(gè)事務(wù)需要按條件執(zhí)行時(shí),就要使用這個(gè)命令將給定的鍵設(shè)置為受監(jiān)控的

UNWATCH #清除所有先前為一個(gè)事務(wù)監(jiān)控的鍵,如果你調(diào)用了EXEC或DISCARD命令,那么就不需要手動(dòng)調(diào)用UNWATCH命令

樂觀鎖機(jī)制

樂觀鎖:總是認(rèn)為不會(huì)產(chǎn)生并發(fā)問(wèn)題,每次去取數(shù)據(jù)的時(shí)候總認(rèn)為不會(huì)有其他線程對(duì)數(shù)據(jù)進(jìn)行修改,因此不會(huì)上鎖,但是在更新時(shí)會(huì)判斷其他線程在這之前有沒有對(duì)數(shù)據(jù)進(jìn)行修改,一般會(huì)使用版本號(hào)機(jī)制或檢查再設(shè)置(CAS)操作實(shí)現(xiàn)。

redis通過(guò)WATCH命令實(shí)現(xiàn)樂觀鎖,作為WATCH命令的參數(shù)的鍵會(huì)受到Redis的監(jiān)控,Redis能夠檢測(cè)到它們的變化。在執(zhí)行EXEC命令之前,如果Redis檢測(cè)到至少有一個(gè)鍵被修改了,那么整個(gè)事務(wù)便會(huì)中止運(yùn)行,然后EXEC命令會(huì)返回一個(gè)nil值,提醒用戶事務(wù)運(yùn)行失敗。

注意:WATCH命令需要在MULTI之前執(zhí)行,不然redis會(huì)將其一個(gè)命令放入緩存隊(duì)列中。

示例:在以下示例中通過(guò)一個(gè)客戶端開啟事務(wù)監(jiān)聽name鍵,另一個(gè)客戶端在執(zhí)行EXEC之前修改name鍵,此次事務(wù)將不會(huì)執(zhí)行,并返回nil,如下。

redis4.0入門小結(jié)

redis4.0入門小結(jié)

原子性實(shí)踐

為演示redis嚴(yán)格意義上將不支持原子性,做了一些簡(jiǎn)單實(shí)踐。

redis4.0入門小結(jié)

從上面的結(jié)果可以看出,在開啟事務(wù)前name 值為Rose,在開啟事務(wù)先后執(zhí)行了SET命令和LSET命令,但是LSET命令是錯(cuò)誤的,當(dāng)我們調(diào)用EXEC執(zhí)行事務(wù)完事務(wù)以后,在回頭看事務(wù)中的SET命令已經(jīng)生效,并未回滾,因?yàn)樵诖芜^(guò)程中該命令沒有顯示的報(bào)錯(cuò),所以可以說(shuō)redis的事務(wù)不支持原子性。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI