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