《“Java技術員”成長手冊》,包含框架、存儲、搜索、優化、分佈式等必備知識,都收集在GitHub JavaEgg ,N線互聯網開發必備技能兵器譜,歡迎指導
Redis簡介
Redis:REmote DIctionary Server(遠程字典服務器)。
Redis 是一個全開源免費(BSD許可)的,內存中的數據結構存儲系統,它可以用作數據庫、緩存和消息中間件。一般作爲一個高性能的(key/value)分佈式內存數據庫,基於內存運行並支持持久化的NoSQL數據庫,是當前最熱門的NoSql數據庫之一,也被人們稱爲數據結構服務器
Redis 介紹
redis是一個開源的、使用C語言編寫的、支持網絡交互的、可基於內存也可持久化的Key-Value數據庫。
redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步,所以Redis也可以被看成是一個數據結構服務器。
Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關係數據庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。
Redis支持主從同步。數據可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器。這使得Redis可執行單層樹複製。存盤可以有意無意的對數據進行寫操作。由於完全實現了發佈/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發佈記錄。同步對讀取操作的可擴展性和數據冗餘很有幫助。
redis的官網地址,非常好記,是redis.io。(域名後綴io屬於國家域名,是british Indian Ocean territory,即英屬印度洋領地)目前,Vmware在資助着redis項目的開發和維護
Redis的所有數據都是保存在內存中,然後不定期的通過異步方式保存到磁盤上(這稱爲“半持久化模式”);也可以把每一次數據變化都寫入到一個append only file(aof)裏面(這稱爲“全持久化模式”)。這就是redis提供的兩種持久化的方式,RDB(Redis DataBase)和AOF(Append Only File)。
Redis 特點
Redis是一個開源,先進的key-value存儲,並用於構建高性能,可擴展的Web應用程序的完美解決方案。
Redis從它的許多競爭繼承來的三個主要特點:
-
Redis數據庫完全在內存中,使用磁盤僅用於持久性。
-
相比許多鍵值數據存儲,Redis擁有一套較爲豐富的數據類型。
-
Redis可以將數據複製到任意數量的從服務器。
Redis 優勢
- 異常快速:Redis的速度非常快,每秒能執行約11萬集合,每秒約81000+條記錄。SET操作每秒鐘 110000 次,GET操作每秒鐘 81000 次,網站一般使用Redis作爲緩存服務器。
- 支持豐富的數據類型:Redis支持大多數開發人員已經知道像列表,集合,有序集合,散列數據類型。這使得它非常容易解決各種各樣的問題,因爲我們知道哪些問題是可以處理通過它的數據類型更好。
- 操作都是原子性:所有Redis操作是原子的,這保證瞭如果兩個客戶端同時訪問的Redis服務器將獲得更新後的值。
- MultiUtility工具:Redis是一個多功能實用工具,可以在很多如:緩存,消息傳遞隊列中使用(Redis原生支持發佈/訂閱),在應用程序中,如:Web應用程序會話,網站頁面點擊數等任何短暫的數據;
redis使用場景
- 取最新N個數據的操作
- 排行榜應用,取TOP N 操作
- 需要精確設定過期時間的應用
- 定時器、計數器應用
- Uniq操作,獲取某段時間所有數據排重值
- 實時系統,反垃圾系統
- Pub/Sub構建實時消息系統
- 構建隊列系統
- 緩存
安裝
$ wget http://download.redis.io/releases/redis-5.0.6.tar.gz
$ tar xzf redis-5.0.6.tar.gz
$ cd redis-5.0.6
$ make
新版本的編譯文件在src中(之前在bin目錄),啓動server
$ src/redis-server
啓動客戶端
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
Redis數據類型操作手冊
String(字符串)
string是redis最基本的類型,你可以理解成與Memcached一模一樣的類型,一個key對應一個value。
string類型是二進制安全的。意思是redis的string可以包含任何數據。比如jpg圖片或者序列化的對象 。
Redis 的字符串是動態字符串,是可以修改的字符串,內部結構實現上類似於 Java 的 ArrayList,採用預分配冗餘空間的方式來減少內存的頻繁分配,如圖中所示,內部爲當前字符串實際分配的空間 capacity 一般要高於實際字符串長度 len。當字符串長度小於 1M 時,擴容都是加倍現有的空間,如果超過 1M,擴容時一次只會多擴 1M 的空間。需要注意的是字符串最大長度爲 512M。
Hash(字典)
Redis hash 是一個鍵值對集合。KV模式不變,但V是一個鍵值對。
Redis hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。
Redis 的字典相當於 Java 語言裏面的 HashMap,它是無序字典, 內部實現結構上同 Java 的 HashMap 也是一致的,同樣的數組 + 鏈表二維結構。第一維 hash 的數組位置碰撞時,就會將碰撞的元素使用鏈表串接起來。
List(列表)
Redis 列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素導列表的頭部(左邊)或者尾部(右邊)。
它的底層實際是個鏈表,
Redis 的列表相當於 Java 語言裏面的 LinkedList,注意它是鏈表而不是數組。這意味着 list 的插入和刪除操作非常快,時間複雜度爲 O(1),但是索引定位很慢,時間複雜度爲 O(n)
Redis 的列表結構常用來做異步隊列使用。將需要延後處理的任務結構體序列化成字符串塞進 Redis 的列表,另一個線程從這個列表中輪詢數據進行處理
右邊進左邊出:隊列
> rpush books python java golang
(integer) 3
\> llen books
(integer) 3
\> lpop books
"python"
\> lpop books
"java"
\> lpop books
"golang"
\> lpop books
(nil)
右邊進右邊出:棧
> rpush books python java golang
(integer) 3
\> rpop books
"golang"
\> rpop books
"java"
\> rpop books
"python"
\> rpop books
(nil)
Set(集合)
Redis的Set是string類型的無序集合。它是通過HashTable實現的, 相當於 Java 語言裏面的 HashSet,它內部的鍵值對是無序的唯一的。它的內部實現相當於一個特殊的字典,字典中所有的 value 都是一個值NULL
。
zset(sorted set:有序集合)
Redis zset 和 set 一樣也是string類型元素的集合,且不允許重複的成員。不同的是每個元素都會關聯一個double類型的分數。
redis正是通過分數來爲集合中的成員進行從小到大的排序。zset的成員是唯一的,但分數(score)卻可以重複。
它類似於 Java 的 SortedSet 和 HashMap 的結合體,一方面它是一個 set,保證了內部 value 的唯一性,另一方面它可以給每個 value 賦予一個 score,代表這個 value 的排序權重。它的內部實現用的是一種叫做「跳躍列表」的數據結構。
redis常見數據類型查閱:
Key(鍵)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
DEL | DEL key [key …] | 刪除給定的一個或多個 key。 不存在的 key 會被忽略 | |
DUMP | DUMP key | 序列化給定 key ,並返回被序列化的值,使用 RESTORE 命令可以將這個值反序列化爲 Redis 鍵 | |
EXISTS | EXISTS key | 檢查給定 key 是否存在 | |
EXPIRE | EXPIRE key seconds | 爲給定 key 設置生存時間,當 key 過期時(生存時間爲 0 ),它會被自動刪除 | |
PERSIST | PERSIST key | 移除 key 的過期時間,key 將持久保持。 | |
EXPIREAT | EXPIREAT key timestamp | EXPIREAT 的作用和 EXPIRE 類似,都用於爲 key 設置生存時間。 不同在於 EXPIREAT 命令接受的時間參數是 UNIX 時間戳(unix timestamp) | EXPIREAT cache 1355292000 # 這個 key 將在 2012.12.12 過期 |
KEYS | KEYS pattern | 查找所有符合給定模式 pattern 的 key | KEYS * # 匹配數據庫內所有 key |
MOVE | MOVE key db | 將當前數據庫的 key 移動到給定的數據庫 db 當中如果當前數據庫(源數據庫)和給定數據庫(目標數據庫)有相同名字的給定 key ,或者 key 不存在於當前數據庫,那麼 MOVE 沒有任何效果。 因此,也可以利用這一特性,將 MOVE 當作鎖(locking)原語(primitive) | MOVE song 1 # 將 song 移動到數據庫 1 |
TTL | TTL key | 以秒爲單位,返回給定 key 的剩餘生存時間(TTL, time to live)當 key 不存在時,返回 -2 。當 key 存在但沒有設置剩餘生存時間時,返回 -1 。否則,以秒爲單位,返回 key 的剩餘生存時間 | |
PTTL | PTTL key | 以毫秒爲單位返回 key 的剩餘的過期時間。 | |
TYPE | TYPE key | 返回 key 所儲存的值的類型 | |
RENAME | RENAME key newkey | 將 key 改名爲 newkey 。當 key 和 newkey 相同,或者 key 不存在時,返回一個錯誤。當 newkey 已經存在時, RENAME 命令將覆蓋舊值 |
String (字符串)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
SET | SET key value [EX seconds] [PX milliseconds] [NX|XX] | 將字符串值 value 關聯到 key 。如果 key 已經持有其他值, SET 就覆寫舊值,無視類型 | SET key “value” |
MSET | MSET key value [key value …] | 同時設置一個或多個 key-value 對。如果某個給定 key 已經存在,那麼 MSET 會用新值覆蓋原來的舊值,如果這不是你所希望的效果,請考慮使用 MSETNX 命令:它只會在所有給定 key 都不存在的情況下進行設置操作 | MSET date “2012.3.30” time “11:00 a.m.” weather “sunny” |
SETNX | SETNX key value | 將 key 的值設爲 value ,當且僅當 key 不存在。若給定的 key 已經存在,則 SETNX 不做任何動作 SETNX 是『SET if Not eXists』(如果不存在,則 SET)的簡寫 | |
MSETNX | MSETNX key value [key value …] | 同時設置一個或多個 key-value 對,當且僅當所有給定 key 都不存在。即使只有一個給定 key 已存在, MSETNX 也會拒絕執行所有給定 key 的設置操作 | |
SETRANGE | SETRANGE key offset value | 用 value 參數覆寫(overwrite)給定 key 所儲存的字符串值,從偏移量 offset 開始。不存在的 key 當作空白字符串處理 | |
SETBIT | SETBIT key offset value | 對 key 所儲存的字符串值,設置或清除指定偏移量上的位(bit) | GETBIT bit 100 # bit 默認被初始化爲 0 |
SETEX | SETEX key seconds value | 將值 value 關聯到 key ,並將 key 的生存時間設爲 seconds (以秒爲單位)。如果 key 已經存在, SETEX 命令將覆寫舊值。 | |
PSETEX | PSETEX key milliseconds value | 這個命令和 SETEX 命令相似,但它以毫秒爲單位設置 key 的生存時間,而不是像 SETEX 命令那樣,以秒爲單位 | |
STRLEN | STRLEN key | 返回 key 所儲存的字符串值的長度。當 key 儲存的不是字符串值時,返回一個錯誤 | |
GET | GET key | 返回 key 所關聯的字符串值。如果 key 不存在那麼返回特殊值 nil | |
MGET | MGET key [key …] | 返回所有(一個或多個)給定 key 的值。如果給定的 key 裏面,有某個 key 不存在,那麼這個 key 返回特殊值 nil 。因此,該命令永不失敗 | |
GETRANGE | GETRANGE key start end | 返回 key 中字符串值的子字符串,字符串的截取範圍由 start 和 end 兩個偏移量決定(包括 start 和 end 在內)。負數偏移量表示從字符串最後開始計數, -1 表示最後一個字符, -2 表示倒數第二個,以此類推。 | GETRANGE greeting 0 4 |
GETSET | GETSET key value | 將給定 key 的值設爲 value ,並返回 key 的舊值(old value)。當 key 存在但不是字符串類型時,返回一個錯誤。 | |
GETBIT | GETBIT key offset | 對 key 所儲存的字符串值,獲取指定偏移量上的位(bit)。當 offset 比字符串值的長度大,或者 key 不存在時,返回 0 | |
APPEND | APPEND key value | 如果 key 已經存在並且是一個字符串, APPEND 命令將 value 追加到 key 原來的值的末尾。如果 key 不存在, APPEND 就簡單地將給定 key 設爲 value ,就像執行 SET key value 一樣 | |
DECR | DECR key | 將 key 中儲存的數字值減一。如果 key 不存在,那麼 key 的值會先被初始化爲 0 ,然後再執行 DECR 操作 | redis> SET failure_times 10OK redis> DECR failure_times(integer) 9 |
DECRBY | DECRBY key decrement | 將 key 所儲存的值減去減量 decrement | |
INCR | INCR key | 將 key 中儲存的數字值增一。如果 key 不存在,那麼 key 的值會先被初始化爲 0 ,然後再執行 INCR 操作 | |
INCRBY | INCRBY key increment | 將 key 所儲存的值加上增量 increment | |
INCRBYFLOAT | INCRBYFLOAT key increment | 爲 key 中所儲存的值加上浮點數增量 increment | INCRBYFLOAT mykey 0.1 |
BITCOUNT | BITCOUNT key [start] [end] | 計算給定字符串中,被設置爲 1 的比特位的數量 | |
BITOP | BITOP operation destkey key [key …] | 對一個或多個保存二進制位的字符串 key 進行位元操作,並將結果保存到 destkey 上。 |
☆☆位圖:
String命令中包含了一種特殊的操作,直接操作bit,某些特殊場景下,會節省存儲空間。可以在存取bool型數據的場景使用,比如存取用戶男女比例,用戶某一段日期簽到記錄,
在我們平時開發過程中,會有一些 bool 型數據需要存取,比如用戶一年的簽到記錄,簽了是 1,沒簽是 0,要記錄 365 天。如果使用普通的 key/value,每個用戶要記錄 365 個,當用戶上億的時候,需要的存儲空間是驚人的。
爲了解決這個問題,Redis 提供了位圖數據結構,這樣每天的簽到記錄只佔據一個位,365 天就是 365 個位,46 個字節 (一個稍長一點的字符串) 就可以完全容納下,這就大大節約了存儲空間。
位圖不是特殊的數據結構,它的內容其實就是普通的字符串,也就是 byte 數組。我們可以使用普通的 get/set 直接獲取和設置整個位圖的內容,也可以使用位圖操作 getbit/setbit 等將 byte 數組看成「位數組」來處理
Redis 的位數組是自動擴展,如果設置了某個偏移位置超出了現有的內容範圍,就會自動將位數組進行零擴充。
接下來我們使用 redis-cli 設置第一個字符,也就是位數組的前 8 位,我們只需要設置值爲 1 的位,如上圖所示,h 字符只有 1/2/4 位需要設置,e 字符只有 9/10/13/15 位需要設置。值得注意的是位數組的順序和字符的位順序是相反的。
127.0.0.1:6379> setbit s 1 1
(integer) 0
127.0.0.1:6379> setbit s 2 1
(integer) 0
127.0.0.1:6379> setbit s 4 1
(integer) 0
127.0.0.1:6379> setbit s 9 1
(integer) 0
127.0.0.1:6379> setbit s 10 1
(integer) 0
127.0.0.1:6379> setbit s 13 1
(integer) 0
127.0.0.1:6379> setbit s 15 1
(integer) 0
127.0.0.1:6379> get s
"he"
上面這個例子可以理解爲「零存整取」,同樣我們還也可以「零存零取」,「整存零取」。「零存」就是使用 setbit 對位值進行逐個設置,「整存」就是使用字符串一次性填充所有位數組,覆蓋掉舊值。
bitcount和bitop, bitpos,bitfield 都是操作位圖的指令。
List(列表)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
LPUSH | LPUSH key value [value …] | 將一個或多個值 value 插入到列表 key 的表頭如果有多個 value 值,那麼各個 value 值按從左到右的順序依次插入到表頭 | 正着進反着出 |
LPUSHX | LPUSHX key value | 將值 value 插入到列表 key 的表頭,當且僅當 key 存在並且是一個列表。和 LPUSH 命令相反,當 key 不存在時, LPUSHX 命令什麼也不做 | |
RPUSH | RPUSH key value [value …] | 將一個或多個值 value 插入到列表 key 的表尾(最右邊) | 怎麼進怎麼出 |
RPUSHX | RPUSHX key value | 將值 value 插入到列表 key 的表尾,當且僅當 key 存在並且是一個列表。和 RPUSH 命令相反,當 key 不存在時, RPUSHX 命令什麼也不做。 | |
LPOP | LPOP key | 移除並返回列表 key 的頭元素。 | |
BLPOP | BLPOP key [key …] timeout | 移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止 | |
RPOP | RPOP key | 移除並返回列表 key 的尾元素。 | |
BRPOP | BRPOP key [key …] timeout | 移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。 | |
BRPOPLPUSH | BRPOPLPUSH source destination timeout | 從列表中彈出一個值,將彈出的元素插入到另外一個列表中並返回它; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。 | |
RPOPLPUSH | RPOPLPUSH source destinationb | 命令 RPOPLPUSH 在一個原子時間內,執行以下兩個動作:將列表 source 中的最後一個元素(尾元素)彈出,並返回給客戶端。將 source 彈出的元素插入到列表 destination ,作爲 destination 列表的的頭元素 | RPOPLPUSH list01 list02 |
LSET | LSET key index value | 將列表 key 下標爲 index 的元素的值設置爲 value | |
LLEN | LLEN key | 返回列表 key 的長度。如果 key 不存在,則 key 被解釋爲一個空列表,返回 0 .如果 key 不是列表類型,返回一個錯誤 | |
LINDEX | LINDEX key index | 返回列表 key 中,下標爲 index 的元素。下標(index)參數 start 和 stop 都以 0 爲底,也就是說,以 0 表示列表的第一個元素,以 1 表示列表的第二個元素,以此類推。相當於 Java 鏈表的get(int index) 方法,它需要對鏈表進行遍歷,性能隨着參數index 增大而變差。 |
|
LRANGE | LRANGE key start stop | 返回列表 key 中指定區間內的元素,區間以偏移量 start 和 stop 指定 | |
LREM | LREM key count value | 根據參數 count 的值,移除列表中與參數 value 相等的元素 | |
LTRIM | LTRIM key start stop | 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除 | |
LINSERT | LINSERT key BEFORE|AFTER pivot value | 將值 value 插入到列表 key 當中,位於值 pivot 之前或之後。當 pivot 不存在於列表 key 時,不執行任何操作。當 key 不存在時, key 被視爲空列表,不執行任何操作。如果 key 不是列表類型,返回一個錯誤。 | LINSERT list01 before c++ c#(在c++之前加上C#) |
Hash(哈希表)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
HSET | HSET key field value | 將哈希表 key 中的域 field 的值設爲 value 。如果 key 不存在,一個新的哈希表被創建並進行 HSET 操作。如果域 field 已經存在於哈希表中,舊值將被覆蓋。 | |
HMSET | HMSET key field value [field value …] | 同時將多個 field-value (域-值)對設置到哈希表 key 中。此命令會覆蓋哈希表中已存在的域。 | |
HSETNX | HSETNX key field value | 將哈希表 key 中的域 field 的值設置爲 value ,當且僅當域 field 不存在。若域 field 已經存在,該操作無效 | |
HGET | HGET key field | 返回哈希表 key 中給定域 field 的值 | |
HMGET | HMGET key field [field …] | 返回哈希表 key 中,一個或多個給定域的值。 | |
HGETALL | HGETALL key | 返回哈希表 key 中,所有的域和值。在返回值裏,緊跟每個域名(field name)之後是域的值(value),所以返回值的長度是哈希表大小的兩倍 | |
HDEL | HDEL key field [field …] | 刪除哈希表 key 中的一個或多個指定域,不存在的域將被忽略 | |
HEXISTS | HEXISTS key field | 查看哈希表 key 中,給定域 field 是否存在 | |
HLEN | HLEN key | 返回哈希表 key 中域的數量 | |
HKEYS | HKEYS key | 返回哈希表 key 中的所有域 | |
HVALS | HVALS key | 返回哈希表 key 中所有域的值 | |
HSTRLEN | HSTRLEN key field | 返回哈希表 key 中,與給定域 field 相關聯的值的字符串長度(string length)。如果給定的鍵或者域不存在,那麼命令返回 0 | |
HINCRBY | HINCRBY key field increment | 爲哈希表 key 中的域 field 的值加上增量 increment | |
HINCRBYFLOAT | HINCRBYFLOAT key field increment | 爲哈希表 key 中的域 field 加上浮點數增量 increment | |
HSCAN | HSCAN key cursor [MATCH pattern] [COUNT count] | 迭代哈希表中的鍵值對。 |
Set(集合)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
SADD | SADD key member [member …] | 將一個或多個 member 元素加入到集合 key 當中,已經存在於集合的 member 元素將被忽略。假如 key 不存在,則創建一個只包含 member 元素作成員的集合。當 key 不是集合類型時,返回一個錯誤 | |
SCARD | SCARD key | 返回集合 key 的基數(集合中元素的數量)。 | |
SDIFF | SDIFF key [key …] | 返回一個集合的全部成員,該集合是所有給定集合之間的差集。不存在的 key 被視爲空集。 | 差集 |
SDIFFSTORE | SDIFFSTORE destination key [key …] | 這個命令的作用和 SDIFF 類似,但它將結果保存到 destination 集合,而不是簡單地返回結果集。如果 destination 集合已經存在,則將其覆蓋。destination 可以是 key 本身。 | |
SINTER | SINTER key [key …] | 返回一個集合的全部成員,該集合是所有給定集合的交集。不存在的 key 被視爲空集。當給定集合當中有一個空集時,結果也爲空集(根據集合運算定律) | 交集 |
SINTERSTORE | SINTERSTORE destination key [key …] | 這個命令類似於 SINTER 命令,但它將結果保存到 destination 集合,而不是簡單地返回結果集。如果 destination 集合已經存在,則將其覆蓋。destination 可以是 key 本身 | |
SUNION | SUNION key [key …] | 返回一個集合的全部成員,該集合是所有給定集合的並集。不存在的 key 被視爲空集 | 並集 |
SUNIONSTORE | SUNIONSTORE destination key [key …] | 這個命令類似於 SUNION 命令,但它將結果保存到 destination 集合,而不是簡單地返回結果集。如果 destination 已經存在,則將其覆蓋。destination 可以是 key 本身 | |
SMEMBERS | SMEMBERS key | 返回集合 key 中的所有成員。不存在的 key 被視爲空集合 | |
SRANDMEMBER | SRANDMEMBER key [count] | 如果命令執行時,只提供了 key 參數,那麼返回集合中的一個隨機元素 | |
SISMEMBER | SISMEMBER key member | 判斷 member 元素是否集合 key 的成員 | |
SMOVE | SMOVE source destination member | 將 member 元素從 source 集合移動到 destination 集合。 | |
SPOP | SPOP key | 移除並返回集合中的一個隨機元素。如果只想獲取一個隨機元素,但不想該元素從集合中被移除的話,可以使用 SRANDMEMBER 命令。 | |
SREM | SREM key member [member …] | 移除集合 key 中的一個或多個 member 元素,不存在的 member 元素會被忽略。當 key 不是集合類型,返回一個錯誤 | |
SSCAN | SSCAN key cursor [MATCH pattern] [COUNT count] | 迭代集合中的元素 |
SortedSet(有序集合)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
ZADD | ZADD key score1 member1 [score2 member2] | 向有序集合添加一個或多個成員,或者更新已存在成員的分數 | |
ZCARD | ZCARD key | 返回有序集 key 的基數。 | |
ZCOUNT | ZCOUNT key min max | 返回有序集 key 中, score 值在 min 和 max 之間(默認包括 score 值等於 min 或 max )的成員的數量。關於參數 min 和 max 的詳細使用方法,請參考 ZRANGEBYSCORE 命令。 | |
ZRANGE | ZRANGE key start stop [WITHSCORES] | 返回有序集 key 中,指定區間內的成員。其中成員的位置按 score 值遞增(從小到大)來排序 | |
ZREVRANGE | ZREVRANGE key start stop [WITHSCORES] | 返回有序集 key 中,指定區間內的成員。其中成員的位置按 score 值遞減(從大到小)來排列。具有相同 score 值的成員按字典序的逆序(reverse lexicographical order)排列。除了成員按 score 值遞減的次序排列這一點外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一樣。 | |
ZREVRANGEBYSCORE | ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] | 返回有序集 key 中, score 值介於 max 和 min 之間(默認包括等於 max 或 min )的所有的成員。有序集成員按 score 值遞減(從大到小)的次序排列。 | |
ZREVRANK | ZREVRANK key member | 返回有序集 key 中成員 member 的排名。其中有序集成員按 score 值遞減(從大到小)排序。排名以 0 爲底,也就是說, score 值最大的成員排名爲 0 。使用 ZRANK 命令可以獲得成員按 score 值遞增(從小到大)排列的排名。 | |
ZSCORE | ZSCORE key member | 返回有序集 key 中,成員 member 的 score 值。如果 member 元素不是有序集 key 的成員,或 key 不存在,返回 nil 。 | |
ZRANGEBYSCORE | ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] | 返回有序集 key 中,所有 score 值介於 min 和 max 之間(包括等於 min 或 max )的成員。有序集成員按 score 值遞增(從小到大)次序排列。 | |
ZRANK | ZRANK key member | 返回有序集 key 中成員 member 的排名。其中有序集成員按 score 值遞增(從小到大)順序排列。 | |
ZINCRBY | ZINCRBY key increment member | 爲有序集 key 的成員 member 的 score 值加上增量 increment | |
ZREM | ZREM key member [member …] | 移除有序集 key 中的一個或多個成員,不存在的成員將被忽略。當 key 存在但不是有序集類型時,返回一個錯誤。 | |
ZREMRANGEBYRANK | ZREMRANGEBYRANK key start stop | 移除有序集 key 中,指定排名(rank)區間內的所有成員 | |
ZREMRANGEBYSCORE | ZREMRANGEBYSCORE key min max | 移除有序集 key 中,所有 score 值介於 min 和 max 之間(包括等於 min 或 max )的成員。 | |
ZUNIONSTORE | ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX] | 計算給定的一個或多個有序集的並集,其中給定 key 的數量必須以 numkeys 參數指定,並將該並集(結果集)儲存到 destination 。默認情況下,結果集中某個成員的 score 值是所有給定集下該成員 score 值之 和 。 | |
ZINTERSTORE | ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX] | 計算給定的一個或多個有序集的交集,其中給定 key 的數量必須以 numkeys 參數指定,並將該交集(結果集)儲存到 destination 。默認情況下,結果集中某個成員的 score 值是所有給定集下該成員 score 值之和. | |
ZSCAN | ZSCAN key cursor [MATCH pattern] [COUNT count] | 迭代有序集合中的元素(包括元素成員和元素分值) | |
ZRANGEBYLEX | ZRANGEBYLEX key min max [LIMIT offset count] | 當有序集合的所有成員都具有相同的分值時,有序集合的元素會根據成員的字典序(lexicographical ordering)來進行排序,而這個命令則可以返回給定的有序集合鍵 key 中,值介於 min 和 max 之間的成員。 | |
ZLEXCOUNT | ZLEXCOUNT key min max | 對於一個所有成員的分值都相同的有序集合鍵 key 來說,這個命令會返回該集合中,成員介於 min 和 max 範圍內的元素數量。這個命令的 min 參數和 max 參數的意義和 ZRANGEBYLEX 命令的 min 參數和 max 參數的意義一樣 | |
ZREMRANGEBYLEX | ZREMRANGEBYLEX key min max | 對於一個所有成員的分值都相同的有序集合鍵 key 來說,這個命令會移除該集合中,成員介於 min 和 max 範圍內的所有元素。這個命令的 min 參數和 max 參數的意義和 ZRANGEBYLEX 命令的 min 參數和 max 參數的意義一樣 |
HyperLogLog
Redis 在 2.8.9 版本添加了 HyperLogLog 結構。
場景:可以用來統計站點的UV…
Redis HyperLogLog 是用來做基數統計的算法,HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定 的、並且是很小的。但是會有誤差。
命令 | 用法 | 描述 |
---|---|---|
pfadd | [PFADD key element [element …] | 添加指定元素到 HyperLogLog 中 |
pfcount | [PFCOUNT key [key …] | 返回給定 HyperLogLog 的基數估算值。 |
pfmerge | [PFMERGE destkey sourcekey [sourcekey …] | 將多個 HyperLogLog 合併爲一個 HyperLogLog |
public class JedisTest {
public static void main(String[] args) {
Jedis jedis = new Jedis();
for (int i = 0; i < 100000; i++) {
jedis.pfadd("codehole", "user" + i);
}
long total = jedis.pfcount("codehole");
System.out.printf("%d %d\n", 100000, total);
jedis.close();
}
}