redis作為nosql家族中非常熱門的一員,也是被大型互聯(lián)網(wǎng)公司所青睞,無論你是開發(fā)、測試或者運維,學(xué)習(xí)掌握它總會為你的職業(yè)生涯增色添彩。
當然,你或多或少已經(jīng)了解redis,但是你是否了解其中的某些細節(jié),本片文章將詳細介紹redis基礎(chǔ),后續(xù)也會介紹其高級部分如、持久化、復(fù)制、集群等內(nèi)容,希望對你有所幫助。
自redis3.0發(fā)布已經(jīng)3年了,redis目前官方提供的redis穩(wěn)定版本是4.0,以下示例均在4.0版本上進行。
概述
redis(REmote DIctionary Server)是一個由Salvatore Sanfilippo寫key-value存儲系統(tǒng),它由C語言編寫、遵守BSD協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value類型的數(shù)據(jù)庫,并提供多種語言的API。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實現(xiàn)了master-slave(主從)同步,redis在3.0版本推出集群模式。
特點、優(yōu)勢
對比memcache
源碼部署
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啟動腳本針對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 #后臺運行 ####啟動與停止 /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
二進制文件說明
redis安裝完成后會有以下可執(zhí)行文件(window下是exe文件)生成,下面是各個文件的作用。
redis-server #Redis服務(wù)器和Sentinel服務(wù)器,啟動時候可使用--sentinel指定為哨兵 redis-cli #Redis命令行客戶端 redis-benchmark #Redis性能測試工具 redis-check-aof #AOF文件修復(fù)工具 redis-check-dump #RDB文件檢測工具 redis-sentinel #Sentinel服務(wù)器,4.0版本已經(jīng)做了軟鏈接到redis-server
redis所有的配置參數(shù)都可以通過客戶端通過“CONFIG GET 參數(shù)名” 獲取,參數(shù)名支持通配符,如*代表所有。所得結(jié)果并按照順序分組,第一個返回結(jié)果是參數(shù)名,第二個結(jié)果是參數(shù)對應(yīng)的值。
除了查看配置還可以使用CONFIG SET修改配置,寫入配置文件使用CONFIG REWRITE,使用時是需要注意某些關(guān)于服務(wù)配置參數(shù)慎重修改,如bind。
配置參數(shù)以及解釋,需要注意的是,有些配置是4.0.10新增的,有些配置已經(jīng)廢除,如vm相關(guān)配置,和集群相關(guān)配置在集群篇章在進行補充。
logfile #日志文件位置及文件名稱 bind 0.0.0.0 #監(jiān)聽地址,可以有多個 如bind 0.0.0.0 127.0.0.1 daemonize yes #yes啟動守護進程運行,即后臺運行,no表示不啟用 pidfile /var/run/redis.pid # 當redis在后臺運行的時候,Redis默認會把pid文件在在/var/run/redis.pid,也可以配置到其他地方。 # 當運行多個redis服務(wù)時,需要指定不同的pid文件和端口 port 6379 # 指定redis運行的端口,默認是6379 unixsocket #sock文件位置 unixsocketperm #sock文件權(quán)限 timeout 0 # 設(shè)置客戶端連接時的超時時間,單位為秒。當客戶端在這段時間內(nèi)沒有發(fā)出任何指令,那么關(guān)閉該連接, 0是關(guān)閉此設(shè)置 loglevel debug # 指定日志記錄級別,Redis總共支持四個級別:debug、verbose、notice、warning,默認為verbose logfile "" # 日志文件配置,默認值為stdout,標準輸出,若后臺模式會輸出到/dev/null syslog-enabled # 是否以syslog方式記錄日志,yes開啟no禁用,與該配置相關(guān)配置syslog-ident 和syslog-facility local0 分別是指明syslog的ident和facility databases 16 #配置可用的數(shù)據(jù)庫個數(shù),默認值為16,默認數(shù)據(jù)庫為0,數(shù)據(jù)庫范圍在0-(database-1)之間 always-show-logo yes #4.0以后新增配置 #是否配置日志顯示redis徽標,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個key被改變則做一次快照 #save 300 10 300秒內(nèi)至少有300個key被改變則做一次快照 #save 60 10000 60秒內(nèi)至少有10000個key被改變則做一次快照 dbfilename dump.rdb #rdb持久化存儲數(shù)據(jù)庫文件名,默認為dump.rdb stop-write-on-bgsave-error yes #yes代表當使用bgsave命令持久化出錯時候停止寫RDB快照文件,no則代表繼續(xù)寫 rdbchecksum yes #開啟rdb文件校驗 dir "/etc" #數(shù)據(jù)文件存放目錄,rdb快照文件和aof文件都會存放至該目錄 ################################# 復(fù)制相關(guān)配置參數(shù) ################################# slaveof masterip> masterport> #設(shè)置該數(shù)據(jù)庫為其他數(shù)據(jù)庫的從數(shù)據(jù)庫,設(shè)置當本機為slave服務(wù)時,設(shè)置master服務(wù)的IP地址及端口,在Redis啟動時,它會自動從master進行數(shù)據(jù)同步 masterauth master-password> #主從復(fù)制中,設(shè)置連接master服務(wù)器的密碼(前提master啟用了認證) slave-serve-stale-data yes # 當從庫同主機失去連接或者復(fù)制正在進行,從機庫有兩種運行方式: # 1) 如果slave-serve-stale-data設(shè)置為yes(默認設(shè)置),從庫會繼續(xù)相應(yīng)客戶端的請求 # 2) 如果slave-serve-stale-data是指為no,除了INFO和SLAVOF命令之外的任何請求都會返回一個錯誤"SYNC with master in progress" repl-ping-slave-period 10 #從庫會按照一個時間間隔向主庫發(fā)送PING命令來判斷主服務(wù)器是否在線,默認是10秒 repl-timeout 60 #設(shè)置主庫批量數(shù)據(jù)傳輸時間或者ping回復(fù)時間間隔超時時間,默認值是60秒 # 一定要確保repl-timeout大于repl-ping-slave-period repl-backlog-size 1mb #設(shè)置復(fù)制積壓大小,只有當至少有一個從庫連入才會釋放。 slave-priority 100 #當主庫發(fā)生宕機時候,哨兵會選擇優(yōu)先級最高的一個稱為主庫,從庫優(yōu)先級配置默認100,數(shù)值越小優(yōu)先級越高 min-slaves-to-write 3 min-slaves-max-lag 10 #設(shè)置某個時間斷內(nèi),如果從庫數(shù)量小于該某個值則不允許主機進行寫操作,以上參數(shù)表示10秒內(nèi)如果主庫的從節(jié)點小于3個,則主庫不接受寫請求,min-slaves-to-write 0代表關(guān)閉此功能。 ################################## 安全相關(guān)配置 ################################### requirepass #客戶端連接認證的密碼,默認為空,即不需要密碼,若配置則命令行使用AUTH進行認證 maxclients 10000 # 設(shè)置同一時間最大客戶端連接數(shù),4.0默認10000,Redis可以同時打開的客戶端連接數(shù)為Redis進程可以打開的最大文件描述符數(shù), # 如果設(shè)置 maxclients 0,表示不作限制。 # 當客戶端連接數(shù)到達限制時,Redis會關(guān)閉新的連接并向客戶端返回max number of clients reached錯誤信息 maxmemory 4gb #設(shè)置最大使用的內(nèi)存大小 maxmemory-policy noeviction #設(shè)置達到最大內(nèi)存采取的策略: # volatile-lru -> 利用LRU算法移除設(shè)置過過期時間的key (LRU:最近使用 Least Recently Used ) # allkeys-lru -> 利用LRU算法移除任何key # volatile-random -> 移除設(shè)置過過期時間的隨機key # allkeys->random -> remove a random key, any key # volatile-ttl -> 移除即將過期的key(minor TTL) # 4.0默認noeviction代表不刪除任何key,只在寫操作時候返回錯誤。 maxmemory-samples 5 #LRU,LFU等算法樣本設(shè)置,默認5個key ############################## AOF相關(guān)配置############################### appendonly no # 設(shè)置AOF持久化,yes開啟,no禁用,開啟后redis會把所接收到的每一次寫操作請求都追加到appendonly.aof文件中,當redis重新啟動時,會從該文件恢復(fù)出之前的狀態(tài)。 # 但是這樣會造成appendonly.aof文件過大,所以redis還支持了BGREWRITEAOF指令,對appendonly.aof 進行重寫。 appendfilename "appendonly.aof" #設(shè)置AOF文件名 appendfsync everysec # AOF文件寫策略,Redis支持三種同步AOF文件的策略: # no: 不進行同步,交給操作系統(tǒng)去執(zhí)行 ,速度較快 # always: always表示每次有寫操作都調(diào)用fsync方法強制內(nèi)核將該寫操作寫入到文件,速度會慢, 但是安全,因為每次寫操作都在AOF文件中. # everysec: 表示對寫操作進行累積,每秒同步一次,折中方案. # 默認是"everysec",按照速度和安全折中這是最好的。 no-appendfsync-on-rewrite no # AOF策略設(shè)置為always或者everysec時,后臺處理進程(后臺保存或者AOF日志重寫)會執(zhí)行大量的I/O操作 # 在某些Linux配置中會阻止過長的fsync()請求。注意現(xiàn)在沒有任何修復(fù),即使fsync在另外一個線程進行處理,為了減緩這個問題,可以設(shè)置下面這個參數(shù)no-appendfsync-on-rewrite auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb #當AOF文件增長到一定大小的時候Redis能夠調(diào)用BGREWRITEAOF對日志文件進行重寫,它是這樣工作的:Redis會記住上次進行些日志后文件的大小(如果從開機以來還沒進行過重寫,那日子大小在開機的時候確定)。 #基礎(chǔ)大小會同現(xiàn)在的大小進行比較。如果現(xiàn)在的大小比基礎(chǔ)大小大制定的百分比,重寫功能將啟動 # 同時需要指定一個最小大小用于AOF重寫,這個用于阻止即使文件很小但是增長幅度很大也去重寫AOF文件的情況 # 設(shè)置 percentage 為0就關(guān)閉這個特性 #auto-aof-rewrite-percentage 代表AOF文件每次重寫文件大?。ㄒ园俜謹?shù)代表),100表示百分之百,即當文件增加了1倍(100%),則開始重寫AOF文件 #auto-aof-rewrite-min-size 設(shè)置最小重寫文件大小,避免文件小而執(zhí)行太多次的重寫 aof-load-truncated yes #當redis突然運行崩潰時,會出現(xiàn)aof文件被截斷的情況,Redis可以在發(fā)生這種情況時退出并加載錯誤,以下選項控制此行為。 #如果aof-load-truncated設(shè)置為yes,則加載截斷的AOF文件,Redis服務(wù)器啟動發(fā)出日志以通知用戶該事件。 #否則,如果該選項設(shè)置為no,則服務(wù)器將中止并顯示錯誤并停止啟動。當該選項設(shè)置為no時,用戶需要在重啟之前使用“redis-check-aof”實用程序修復(fù)AOF文件在進行重啟 ################################## 慢查詢配置 ################################### slowlog-log-slower-than 10000 #Redis Slow Log 記錄超過特定執(zhí)行時間的命令。執(zhí)行時間不包括I/O計算比如連接客戶端,返回結(jié)果等,只是命令執(zhí)行時間,可以通過兩個參數(shù)設(shè)置slow log:一個是告訴Redis執(zhí)行超過多少時間被記錄的參數(shù)slowlog-log-slower-than(微秒,因此1000000代表一分鐘 #另一個是slow log 的長度。當一個新命令被記錄的時候最早的命令將被從隊列中移除 slowlog-max-len 128 #慢查詢命令記錄隊列長度設(shè)置,該隊列占用內(nèi)存,可以使用SLOWLOG RESET清空隊列 ############################### 高級配置 ############################### hash-max-zipmap-entries 512 hash-max-zipmap-value 64 # 當hash中包含超過指定元素個數(shù)并且最大的元素沒有超過臨界時,hash將以一種特殊的編碼方式(大大減少內(nèi)存使用)來存儲,這里可以設(shè)置這兩個臨界值 # Redis Hash對應(yīng)Value內(nèi)部實際就是一個HashMap,實際這里會有2種不同實現(xiàn), # 這個Hash的成員比較少時Redis為了節(jié)省內(nèi)存會采用類似一維數(shù)組的方式來緊湊存儲,而不會采用真正的HashMap結(jié)構(gòu),對應(yīng)的value redisObject的encoding為zipmap,當成員數(shù)量增大時會自動轉(zhuǎn)成真正的HashMap,此時encoding為ht。 list-max-ziplist-size -2 #Lists也以特殊方式編碼,以節(jié)省大量空間。 ??梢灾付總€內(nèi)部列表節(jié)點允許的條目數(shù) #作為固定的最大大小或最大元素數(shù)。 #對于固定的最大大小,使用-5到-1表示: #-5:最大大?。?4 Kb - 不建議用于正常工作負載 #-4:最大尺寸:32 Kb - 不推薦 #-3:最大尺寸:16 Kb - 可能不推薦 #-2:最大尺寸:8 Kb - 好 #-1:最大尺寸:4 Kb - 良好 #正數(shù)意味著存儲_exactly_元素數(shù)量 #每個列表節(jié)點。 #性能最高的選項通常為-2(8 Kb大?。┗?1(4 Kb大?。? zset-max-ziplist-entries 128 zset-max-ziplist-value 64 # list數(shù)據(jù)類型多少節(jié)點以下會采用去指針的緊湊存儲格式。 # list數(shù)據(jù)類型節(jié)點值大小小于多少字節(jié)會采用緊湊存儲格式。 activerehashing yes # Redis將在每100毫秒時使用1毫秒的CPU時間來對redis的hash表進行重新hash,可以降低內(nèi)存的使用 # 當你的使用場景中,有非常嚴格的實時性需要,不能夠接受Redis時不時的對請求有2毫秒的延遲的話,把這項配置為no。 # 如果沒有這么嚴格的實時性要求,可以設(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ū)限制可用于強制斷開客戶端,由于某種原因,沒有足夠快地從服務(wù)器讀取數(shù)據(jù),常見的原因是Pub / Sub客戶端不能像很快的消費一條消息,可以為三種不同類型的客戶端設(shè)置不同的限制: #normal - >普通客戶端,包括MONITOR客戶端 #subve - >從服務(wù)器客戶端 #pubsub - >客戶端訂閱了至少一個pubsub通道或模式 #設(shè)置方法:client-output-buffer-limit 軟限制大小 硬限制大小 秒數(shù) #當客戶端達到硬限制大小則立即斷開連接,當客戶端達到軟限制時候并且在設(shè)置的秒數(shù)緩沖大小任然超了,則在設(shè)置的秒數(shù)后斷開連接
通常使用redis不外乎使用其常用的5中數(shù)據(jù)類型:string、list、hash、set、sorted_set,在3.2版本以后新添加geo經(jīng)緯度支持,以下將對其類型的常用操作做說明。
命令使用前言
通大多數(shù)據(jù)庫一樣,redis所有的命令提供了幫助,可以使用help +命令名稱查看其使用方法,幫助信息中不僅有命令用法,還有命令始于版本信息,分組等。
為了友好的使用,redis還將所有命令都進行了分組,同時使用help+@+組名進行查看每個組中所有命令,以下是所有分組信息。
上面以及介紹如何查看命令使用方法,所以在以下數(shù)據(jù)類型操作時候,只舉例常用的命令,更多命令參考https://redis.io/commands
注意:redis在3.2版本新增geo數(shù)據(jù)類型。
generic #一般命令組,對大多數(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ù)操作所有命令
key操作
常用:
DEL key #刪除某個key KEYS pattern #查看符合正則的所有key EXISTS key [key ...] #判斷某個key是否存在,可支持多個,返回存在的個數(shù) EXPIRE key seconds #刷新某個key過期時間 MOVE key db #移動key到某個數(shù)據(jù)庫
示例:
string操作
字符串操作中需要注意的是,redis中的整型也當作字符串處理。
常用:
SET key value [EX seconds] [PX milliseconds] [NX|XX] #設(shè)置key為指定的字符串值。 #參數(shù): #EX seconds – 設(shè)置鍵key的過期時間,單位時秒 #PX milliseconds – 設(shè)置鍵key的過期時間,單位時毫秒 #NX – 只有鍵key不存在的時候才會設(shè)置key的值 #XX – 只有鍵key存在的時候才會設(shè)置key的值 APPEND key value #如果 key 已經(jīng)存在,并且值為字符串,那么這個命令會把 value 追加到原來值(value)的結(jié)尾。 如果 key 不存在,那么它將首先創(chuàng)建一個空字符串的key,再執(zhí)行追加操作,這種情況 APPEND 將類似于 SET 操作。 GET key #獲取key值,不存在則返回nil GETRANGE key start end #獲取指定key值的索引開始位置和結(jié)束位置所對應(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ù)字則報錯 INCR key #數(shù)字類型key 自加操作,與DECR相反 DECRBY key decrement #數(shù)字類型key指定減少數(shù)值 INCRBY key increment #數(shù)字類型key指定增加數(shù)值,與DECRBY相反 STRLEN key #獲取key長度
示例:
list操作
列表中的元素索引從0開始,倒數(shù)的元素可以用“-”+倒數(shù)位置表示,如-2,代表倒數(shù)第二個元素,-1則代表最后一個元素。
Redis列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊。
一個列表最多可以包含 232- 1 個元素 (4294967295, 每個列表超過40億個元素)。
常用:
LPUSH key value [value ...] #從列表左邊放入一個或者多個元素 LPUSHX key value #當列表存在時,從左邊放入一個元素 RPUSH key value [value ...] #從列表右邊放入一個或者多個元素 RPUSHX key value #當列表存在時,從右邊放入一個元素 LSET key index value #根據(jù)索引設(shè)置列表中元素的值,當list不存在是報錯 LINDEX key index #根據(jù)列表索引獲取元素值,索引從0開始 LINSERT key BEFORE|AFTER pivot value #在列表中,基于某個基準點插入值,pivot代表基準點 LLEN key #獲取列表長度 LRANGE key start stop #根據(jù)索引獲取列表中的元素,列表索引最后一個可以使用-1 LREM key count value #從存于 key 的列表里移除前 count 次出現(xiàn)的值為 value 的元素 #count > 0: 從頭往尾移除值為 value 的元素 #count 0: 從尾往頭移除值為 value 的元素 #count = 0: 移除所有值為 value 的元素 LPOP key #從列表左邊刪除一個元素 RPOP key #從列表右邊刪除一個元素 RPOPLPUSH source destination #刪除source列表中的刪除最后一個元素將其追加到destination列表 LTRIM key start stop #根據(jù)索引start和stop保留列表元素
示例:
hash操作
hash操作所有命令都以H開頭。
Redis hash 是一個string類型的field和value的映射表,hash特別適合用于存儲對象。
Redis 中每個 hash 可以存儲 232- 1 鍵值對(40多億)。
常用:
HDEL key field [field ...] #刪除hash表中一個或多個字段 HEXISTS key field #判斷hash表中字段是否存在 HGET key field #獲取hash表中字段的值 HGETALL key #獲取hash表中所有字段 HSET key field value # 設(shè)置hash表中字段的值 HSETNX key field value #只有當字段不存在時候才設(shè)置hash表中字段值, HLEN key #獲取hash表中字段個數(shù) HVALS key #獲取hash表中所有字段的值 HKEYS key #獲取hash表中所有的字段 HSTRLEN key field #獲取hash表中指定字段的值的長度 HMSET key field value [field value ...] #批量設(shè)置hash表中字段的值 HMGET key field [field ...] #批量獲取hash表中字段的值
示例:
集合set操作
Redis 的 Set 是 String 類型的無序集合。集合成員是唯一的,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)。
Redis 中集合是通過哈希表實現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是 O(1)。
集合中最大的成員數(shù)為 232 - 1(4294967295, 每個集合可存儲40多億個成員)。
常用:
SADD key member [member ...] #添加一個或多個元素到集合中 SREM key member [member ...] #刪除一個或多個集合中的元素 SCARD key #獲取集合中元素數(shù)量 SMEMBERS key #返回集合中所有的元素 SINTER key [key ...] #獲取兩個或兩個以上集合的交集 SUNION key [key ...] #獲取兩個或兩個以上集合的并集 SDIFF key [key ...] #獲取兩個或者兩個以上集合的差集 SISMEMBER key member #判斷元素是否是在指定集合中 SMOVE source destination member #移動一個集合中的元素到另一個集合 SPOP key [count] #移除count個集合中元素,count可選參數(shù),默認為1,即移除一個
有序集合操作
Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復(fù)的成員。
不同的是每個元素都會關(guān)聯(lián)一個double類型的分數(shù)。redis正是通過分數(shù)來為集合中的成員進行從小到大的排序。
有序集合的成員是唯一的,但分數(shù)(score)卻可以重復(fù)。
集合是通過哈希表實現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是O(1)。 集合中最大的成員數(shù)為 232 - 1(4294967295, 每個集合可存儲40多億個成員)。
常用:
ZADD key [NX|XX] [CH] [INCR] score member [score member ...] #向一個有序集合添加成員(元素) #參數(shù): #XX: 僅僅更新存在的成員,不添加新成員。 #NX: 不更新存在的成員。只添加新成員。 #CH: 修改返回值為發(fā)生變化的成員總數(shù),原始是返回新添加成員的總數(shù) (CH 是 changed 的意思)。更改的元素是新添加的成員,已經(jīng)存在的成員更新分數(shù)。 所以在命令中指定的成員有相同的分數(shù)將不被計算在內(nèi)。注:在通常情況下,ZADD返回值只計算新添加成員的數(shù)量。 #INCR: 當ZADD指定這個選項時,成員的操作就等同ZINCRBY命令,對成員的分數(shù)進行遞增操作。 ZCARD key #獲取有序集合中元素個數(shù) ZCOUNT key min max #指定分數(shù)范圍的元素個數(shù) ZINCRBY key increment member #為有序集的元素的score值加上增加指定的increment ZRANGE key start stop [WITHSCORES] #根據(jù)有序集合中分數(shù)區(qū)間獲取集合中的元素 ZRANGE key start stop [WITHSCORES] #獲取有序集合中元素的排名 ZREM key member [member ...] #刪除有序集合中一個或多個元素 ZSCORE key member #設(shè)置元素在集合中的分數(shù)
GEO類型操作
Redis的GEO是 3.2 版本的新特性,對GEO(地理位置)的支持。這個功能可以將用戶給定的地理位置信息儲存起來, 并對這些信息進行操作。
geo類型命令不多,總共6個所以這里全部列舉出來了。
GEOADD key longitude latitude member [longitude latitude member ...] #將指定的地理空間位置(緯度、經(jīng)度、名稱)添加到指定的key中 GEODIST key member1 member2 [unit] #返回兩個給定位置之間的距離。如果兩個位置之間的其中一個不存在, 那么命令返回空值。指定單位的參數(shù) unit 必須是以下單位的其中一個: #m 表示單位為米 #km 表示單位為千米 #mi 表示單位為英里 #ft 表示單位為英尺 GEOPOS key member [member ...] #從key里返回所有給定位置元素的位置(經(jīng)度和緯度) GEOHASH key member [member ...] #返回一個或多個位置元素的 Geohash 表示。通常使用表示位置的元素使用不同的技術(shù),使用Geohash位置52點整數(shù)編碼。由于編碼和解碼過程中所使用的初始最小和最大坐標不同,編碼的編碼也不同于標準。此命令返回一個標準的Geohash GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] #以給定的經(jīng)緯度為中心, 返回鍵包含的位置元素當中, 與中心的距離不超過給定最大距離的所有位置元素。 #范圍可以使用以下其中一個單位: #m 表示單位為米。 #km 表示單位為千米。 #mi 表示單位為英里。 #ft 表示單位為英尺。 #在給定以下可選項時, 命令會返回額外的信息: #WITHDIST: 在返回位置元素的同時, 將位置元素與中心之間的距離也一并返回。 距離的單位和用戶給定的范圍單位保持一致。 #WITHCOORD: 將位置元素的經(jīng)度和維度也一并返回。 #WITHHASH: 以 52 位有符號整數(shù)的形式, 返回位置元素經(jīng)過原始 geohash 編碼的有序集合分值。 這個選項主要用于底層應(yīng)用或者調(diào)試, 實際中的作用并不大。 #命令默認返回未排序的位置元素。 通過以下兩個參數(shù), 用戶可以指定被返回位置元素的排序方式: #ASC: 根據(jù)中心的位置, 按照從近到遠的方式返回位置元素。 #DESC: 根據(jù)中心的位置, 按照從遠到近的方式返回位置元素。 #在默認情況下, GEORADIUS 命令會返回所有匹配的位置元素。 雖然用戶可以使用 COUNT count> 選項去獲取前 N 個匹配元素, 但是因為命令在內(nèi)部可能會需要對所有被匹配的元素進行處理, 所以在對一個非常大的區(qū)域進行搜索時, 即使只使用 COUNT 選項去獲取少量元素, 命令的執(zhí)行速度也可能會非常慢。 但是從另一方面來說, 使用 COUNT 選項去減少需要返回的元素數(shù)量, 對于減少帶寬來說仍然是非常有用的。 #返回值: #在沒有給定任何 WITH 選項的情況下, 命令只會返回一個像 [“New York”,”Milan”,”Paris”] 這樣的線性(linear)列表。 #在指定了 WITHCOORD 、 WITHDIST 、 WITHHASH 等選項的情況下, 命令返回一個二層嵌套數(shù)組, 內(nèi)層的每個子數(shù)組就表示一個元素 #在返回嵌套數(shù)組時, 子數(shù)組的第一個元素總是位置元素的名字。 至于額外的信息, 則會作為子數(shù)組的后續(xù)元素, 按照以下順序被返回: #以浮點數(shù)格式返回的中心與位置元素之間的距離, 單位與用戶指定范圍時的單位一致。 #geohash 整數(shù)。 #由兩個元素組成的坐標,分別為經(jīng)度和緯度。 GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] #這個命令和 GEORADIUS 命令一樣, 都可以找出位于指定范圍內(nèi)的元素, 但是 GEORADIUSBYMEMBER 的中心點是由給定的位置元素決定的。
操作示例:
Redis 發(fā)布訂閱(pub/sub)是一種消息通信模式:發(fā)送者(pub)發(fā)送消息,訂閱者(sub)接收消息。
Redis 客戶端可以訂閱任意數(shù)量的頻道。
下圖代表其發(fā)布訂閱之間的關(guān)系
運作原理
每個Redis 服務(wù)器進程都維持著一個表示服務(wù)器狀態(tài)的 redis.h/redisServer結(jié)構(gòu), 結(jié)構(gòu)的pubsub_channels 屬性是一個字典, 這個字典就用于保存訂閱頻道的信息:
struct redisServer { // ... dict *pubsub_channels; // ... };
其中,字典的鍵為正在被訂閱的頻道, 而字典的值則是一個鏈表, 鏈表中保存了所有訂閱這個頻道的客戶端。
比如說,在下圖展示的這個pubsub_channels示例中,client1 、 client2 和 client3 就訂閱了 channel1 , 而client3也同時訂閱了channel2。
當客戶端調(diào)用SUBSCRIBE命令時, 程序就將客戶端和要訂閱的頻道在pubsub_channels字典中關(guān)聯(lián)起來。
SUBSCRIBE命令的行為可以用偽代碼表示如下:
def SUBSCRIBE(client, channels): // 遍歷所有輸入頻道 for channel in channels: // 將客戶端添加到鏈表的末尾 redisServer.pubsub_channels[channel].append(client)
通過pubsub_channels字典, 程序只要檢查某個頻道是否為字典的鍵, 就可以知道該頻道是否正在被客戶端訂閱; 只要取出某個鍵的值, 就可以得到所有訂閱該頻道的客戶端的信息。
了解了pubsub_channels字典的結(jié)構(gòu)之后, 解釋PUBLISH命令的實現(xiàn)就非常簡單了: 當調(diào)用PUBLISH channel message命令, 程序首先根據(jù)channel定位到字典的鍵, 然后將信息發(fā)送給字典值鏈表中的所有客戶端。
訂閱模式
redis的發(fā)布訂閱不僅僅提供簡單的訂閱頻道,還提供模式匹配訂閱。模式訂閱使用命令PSUBSCRIBE實現(xiàn)。
redisServer.pubsub_patterns屬性是一個鏈表,鏈表中保存著所有和模式相關(guān)的信息:
struct redisServer { // ... list *pubsub_patterns; // ... };
鏈表中的每個節(jié)點都包含一個redis.h/pubsubPattern結(jié)構(gòu):
typedef struct pubsubPattern { redisClient *client; robj *pattern; } pubsubPattern;
client 屬性保存著訂閱模式的客戶端,而 pattern 屬性則保存著被訂閱的模式。
每當調(diào)用 PSUBSCRIBE命令訂閱一個模式時, 程序就創(chuàng)建一個包含客戶端信息和被訂閱模式的pubsubPattern結(jié)構(gòu), 并將該結(jié)構(gòu)添加到redisServer.pubsub_patterns鏈表中。
作為例子,下圖展示了一個包含兩個模式的 pubsub_patterns 鏈表, 其中 client123 和 client256 都正在訂閱 tweet.shop.* 模式:
通過遍歷整個pubsub_patterns鏈表,程序可以檢查所有正在被訂閱的模式,以及訂閱這些模式的客戶端。
當執(zhí)行PUBLISH進行命令向channel命令發(fā)送消息時,PUBLISH除了將message 發(fā)送到所有訂閱channel的客戶端之外, 它還會將channel和pubsub_patterns中的模式進行對比, 如果channel和某個模式匹配的話, 那么也將message 發(fā)送到訂閱那個模式的客戶端,例如一個客戶端訂閱了aa.bb.*頻道,那么他會收到來自所有aa.bb開頭的所有頻道消息。
相關(guān)命令
PSUBSCRIBE pattern [pattern ...] #使用模式訂閱一個或多個符合給定模式的頻道 PUNSUBSCRIBE [pattern [pattern ...]] #退訂所有給定模式的頻道 SUBSCRIBE channel [channel ...] #訂閱給定的一個或多個頻道的信息 UNSUBSCRIBE [channel [channel ...]] #指退訂給定的頻道 PUBSUB subcommand [argument [argument ...]] #查看訂閱與發(fā)布系統(tǒng)狀態(tài) PUBLISH channel message #將信息發(fā)送到指定的頻道
實踐
在以下示例中,將分別用SUBSCRIBE命令訂閱aa.bb和使用PSUBSCRIBE模式訂閱頻道aa.bb*。
SUBSCRIBE訂閱:
PSUBSCRIBE訂閱:
此時我們使用PUBSH向aa.bb發(fā)送消息,返回接受到的頻道數(shù),兩個訂閱者都能收到消息。
訂閱者1:
模式訂閱者:
小結(jié)
所謂事務(wù)應(yīng)具有以下特效:原子性(Atomicity), 一致性(Consistency),隔離性(Isolation),持久性(Durability),簡稱ACID,但redis所提供的事務(wù)比較簡單,它通過MULTI、EXEC、DISCARD和WATCH等命令實現(xiàn)事務(wù)。
而Redis只支持簡單的事務(wù),將執(zhí)行命令放入隊列緩存,當程序中有異常或命令出錯,執(zhí)行DISCARD清空緩存隊列不執(zhí)行隊列中命令,其事務(wù)過程有以下特點:
EXEC命令負責(zé)觸發(fā)并執(zhí)行事務(wù)中的所有命令:
特別說明文中的泛原子操作:
涉及命令
MULTI #用于標記事務(wù)塊的開始。Redis會將后續(xù)的命令逐個放入隊列中,然后才能使用EXEC命令執(zhí)行緩存隊列中的命令。 EXEC #執(zhí)行緩存隊列中的命令 DISCARD #清除所有先前在一個事務(wù)中放入隊列的命令,然后恢復(fù)正常的連接狀態(tài),如果使用了WATCH命令,那么DISCARD命令就會將當前連接監(jiān)控的所有鍵取消監(jiān)控。 WATCH key [key ...] #當某個事務(wù)需要按條件執(zhí)行時,就要使用這個命令將給定的鍵設(shè)置為受監(jiān)控的 UNWATCH #清除所有先前為一個事務(wù)監(jiān)控的鍵,如果你調(diào)用了EXEC或DISCARD命令,那么就不需要手動調(diào)用UNWATCH命令
樂觀鎖機制
樂觀鎖:總是認為不會產(chǎn)生并發(fā)問題,每次去取數(shù)據(jù)的時候總認為不會有其他線程對數(shù)據(jù)進行修改,因此不會上鎖,但是在更新時會判斷其他線程在這之前有沒有對數(shù)據(jù)進行修改,一般會使用版本號機制或檢查再設(shè)置(CAS)操作實現(xiàn)。
redis通過WATCH命令實現(xiàn)樂觀鎖,作為WATCH命令的參數(shù)的鍵會受到Redis的監(jiān)控,Redis能夠檢測到它們的變化。在執(zhí)行EXEC命令之前,如果Redis檢測到至少有一個鍵被修改了,那么整個事務(wù)便會中止運行,然后EXEC命令會返回一個nil值,提醒用戶事務(wù)運行失敗。
注意:WATCH命令需要在MULTI之前執(zhí)行,不然redis會將其一個命令放入緩存隊列中。
示例:在以下示例中通過一個客戶端開啟事務(wù)監(jiān)聽name鍵,另一個客戶端在執(zhí)行EXEC之前修改name鍵,此次事務(wù)將不會執(zhí)行,并返回nil,如下。
原子性實踐
為演示redis嚴格意義上將不支持原子性,做了一些簡單實踐。
從上面的結(jié)果可以看出,在開啟事務(wù)前name 值為Rose,在開啟事務(wù)先后執(zhí)行了SET命令和LSET命令,但是LSET命令是錯誤的,當我們調(diào)用EXEC執(zhí)行事務(wù)完事務(wù)以后,在回頭看事務(wù)中的SET命令已經(jīng)生效,并未回滾,因為在次過程中該命令沒有顯示的報錯,所以可以說redis的事務(wù)不支持原子性。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
標簽:畢節(jié) 南寧 伊春 拉薩 泰州 定州 甘南 河源
巨人網(wǎng)絡(luò)通訊聲明:本文標題《redis4.0入門小結(jié)》,本文關(guān)鍵詞 redis4.0,入門,小結(jié),redis4.0,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。