主要是命令相關html
1.redis是基於鍵值對的NoSQL.java
2.redis的值能夠是 string, hash, list, set, zset, bitmaps, hyperloglog, georedis
3.redis的值不只能夠是字符串還能夠是具體的數據結構數據庫
4.redis的2種持久方案:rdb和aof.安全
5.redis-server XXX.conf能夠以conf的配置啓動redis.數據結構
6.redis-cli shutdown能夠關閉redis. 不要使用kill -9 殺死redis進程,可能會形成AOF和複製丟失數據的問題.app
1.keys * 能夠列出全部鍵, dbsize返回全部鍵的總數.dbsize時間複雜度是o(1),keys是o(n).因此鍵太多的時候不要使用keys *dom
另外實驗發現keys 後面*表明任意數量的字符 ?表明單個字符分佈式
2.exists查看鍵是否存在,del刪除鍵,del後面能夠跟任意數量的鍵,好比del a b c .....大數據
3. expire能夠設置鍵過時時間(秒),剩餘時間可使用ttl查看.
127.0.0.1:6379> expire abcd -99 //設置負數,直接過時 (integer) 1 127.0.0.1:6379> ttl abcd (integer) -2 // ttl 大於0表示剩餘秒, -1表示鍵沒設置過時時間, -2表示鍵不存在
4.type key能夠查看key的數據結構
127.0.0.1:6379> set a 1 OK 127.0.0.1:6379> LPUSH b 1 2 3 4 5 (integer) 5 127.0.0.1:6379> type a string 127.0.0.1:6379> type b list
127.0.0.1:6379> type rrr //不存在的key
none
5.type命令返回的是redis對外的數據結構.每種數據結構對內還有N種內部編碼實現.1種內部實現也能夠對應N個外部數據結構.
使用object encoding查看內部數據編碼
127.0.0.1:6379> set a 1 OK 127.0.0.1:6379> set b 2 OK 127.0.0.1:6379> lpush c 1 2 3 4 (integer) 4 127.0.0.1:6379> OBJECT encoding a "int" 127.0.0.1:6379> OBJECT encoding b "int" 127.0.0.1:6379> OBJECT encoding c "ziplist" 127.0.0.1:6379> set d qqq OK 127.0.0.1:6379> OBJECT encoding d "embstr" 127.0.0.1:6379> set e 99999999999999 OK 127.0.0.1:6379> OBJECT encoding e "int" 127.0.0.1:6379> set f 9999999999999999999999999.9999999999999999999999 OK 127.0.0.1:6379> OBJECT encoding f "raw" 127.0.0.1:6379> set g 123.456 OK 127.0.0.1:6379> OBJECT encoding g "embstr" 127.0.0.1:6379> set h 99999999999999999999999999999999999999999999999 OK 127.0.0.1:6379> OBJECT encoding h "raw"
我以爲對於咱們外部其餘語言使用redis來講可能不太關心內部實現而是關心接口返回的外部數據結構..這個有點像java裏經過接口引用具體的集合對象..
6.每次客戶端調用都經歷了發送命令,執行命令,返回結果三個過程.每條命令從客戶端到達服務端之後不會被馬上執行,全部命令都回進入1個隊列中,而後逐個被執行.
1.字符串值不能超過512M
2.實驗
127.0.0.1:6379> set k1 abc //set設置值 OK 127.0.0.1:6379> set k2 def ex 999 //ex設置過時秒數,px設置毫秒數 OK 127.0.0.1:6379> ttl k2 (integer) 997 127.0.0.1:6379> set k1 change xx // xx key 存在才更新否則不操做,用於更新 OK 127.0.0.1:6379> get k1 "change" 127.0.0.1:6379> set k1 qqq OK 127.0.0.1:6379> get k1 "qqq" 127.0.0.1:6379> ttl k2 (integer) 957 127.0.0.1:6379> set k3 ttt nx // nx key 不存在才操做,用於插入 OK 127.0.0.1:6379> get k3 "ttt" 127.0.0.1:6379> set k3 www xx OK 127.0.0.1:6379> get k3 "www" 127.0.0.1:6379> set k3 ppp nx // 不存在key,用nx操做. (nil) 127.0.0.1:6379> get k3 "www"
3.setex和setnx的實驗
setex key seconds value
setnx key value
setex多了1個seconds不知道爲啥
127.0.0.1:6379> exists k1 (integer) 1 127.0.0.1:6379> setnx k1 change //setnx不像set nx返回nil而是返回了操做了0個key (integer) 0 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> exists k2 (integer) 0 127.0.0.1:6379> setnx k2 v2 // 操做成功返回操做了1個key的數量 (integer) 1 127.0.0.1:6379> setnx k2 v22 (integer) 0 127.0.0.1:6379>
127.0.0.1:6379> exists k1
(integer) 1
127.0.0.1:6379> setex k1 999 v999
OK
127.0.0.1:6379> ttl k1
(integer) 996
127.0.0.1:6379>
setnx能夠做爲分佈式鎖的一種方案.由於redis是單線程只有1個操做會成功返回1,其餘都是0
4.mset和mget批量操做
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v4 OK 127.0.0.1:6379> mget k1 k2 k3 k4 1) "v1" 2) "v2" 3) "v4" 4) (nil) 127.0.0.1:6379>
5.計數
incr incrby自增,decr decrby自減
127.0.0.1:6379> set k1 NaN OK 127.0.0.1:6379> INCR k1 //不是數字自增報錯 (error) ERR value is not an integer or out of range 127.0.0.1:6379> set k2 1 OK 127.0.0.1:6379> incr k2 (integer) 2 127.0.0.1:6379> incr k2 (integer) 3 127.0.0.1:6379> get k2 "3" 127.0.0.1:6379> incrby k2 3 (integer) 6 127.0.0.1:6379> incrby k2 NaN //同incr (error) ERR value is not an integer or out of range 127.0.0.1:6379> incrby k2 -3 // 自增指定數量能夠自增負數 (integer) 3 127.0.0.1:6379> decr k1 (error) ERR value is not an integer or out of range 127.0.0.1:6379> decr k2 1 (error) ERR wrong number of arguments for 'decr' command 127.0.0.1:6379> decr k2 (integer) 2 127.0.0.1:6379> decrby k2 2 (integer) 0 127.0.0.1:6379> decrby k2 -9 //同自增 (integer) 9
127.0.0.1:6379> exists k3 (integer) 1 127.0.0.1:6379> del k3 (integer) 1 127.0.0.1:6379> exists k3 (integer) 0 127.0.0.1:6379> incr k3 //操做不存在的key,值直接當成0 (integer) 1 127.0.0.1:6379> del k3 (integer) 1 127.0.0.1:6379> incr k3 3 (error) ERR wrong number of arguments for 'incr' command 127.0.0.1:6379> incrby k3 3 //同incr (integer) 3 127.0.0.1:6379>
127.0.0.1:6379> del k1 (integer) 1 127.0.0.1:6379> del k1 (integer) 0 127.0.0.1:6379> set k1 0.1 OK 127.0.0.1:6379> incr k1 //自增自減只能用於整數 (error) ERR value is not an integer or out of range 127.0.0.1:6379>
6.append追加字符串
127.0.0.1:6379> exists k1 (integer) 1 127.0.0.1:6379> del k1 (integer) 1 127.0.0.1:6379> set k1 hello OK 127.0.0.1:6379> APPEND k1 " world" //返回字符串長度 (integer) 11 127.0.0.1:6379> get k1 "hello world" 127.0.0.1:6379>
127.0.0.1:6379> get k1 "hello world" 127.0.0.1:6379> APPEND k1 "'''" (integer) 14 127.0.0.1:6379> APPEND k1 """" Invalid argument(s) 127.0.0.1:6379> APPEND k1 "\"\"" //追加"能夠用/" (integer) 16 127.0.0.1:6379> get k1 "hello world'''\"\"" 127.0.0.1:6379> set k1 "" OK 127.0.0.1:6379> get k1 "" 127.0.0.1:6379> append k1 "" (integer) 0 127.0.0.1:6379> append k1 " Invalid argument(s) 127.0.0.1:6379> append k1 '' (integer) 0 127.0.0.1:6379> append k1 '"' //或者用'"' (integer) 1 127.0.0.1:6379> get k1 "\"" 127.0.0.1:6379> append k1 "'" (integer) 2 127.0.0.1:6379> get k1 "\"'" 127.0.0.1:6379>
7.用strlen返回字符串長度,用getset能夠設置新值而且返回本來字符串的值(有多是nil).setrange key offset value能夠改變指定位置字符,從0開始計數返回字符串長度
getrange key start end返回substr. 0開始計數,start和end都包括
127.0.0.1:6379> set k1 helloworld OK 127.0.0.1:6379> GETRANGE k1 1 2 "el" 127.0.0.1:6379>
127.0.0.1:6379> GETRANGE k1 2 -1 // -1是最後1個字符串
"lloworld"
127.0.0.1:6379> GETRANGE k1 2 -2
"lloworl"
127.0.0.1:6379> GETRANGE k1 2 0
""
127.0.0.1:6379> GETRANGE k1 2 -0
""
127.0.0.1:6379>
8.字符串內部有3種編碼,int 8字節長整型,embstr<=39字節的字符串,raw>39字節的字符串
127.0.0.1:6379> set k1 9203372036054477800
OK
127.0.0.1:6379> OBJECT encoding k1
"int"
127.0.0.1:6379> set k1 9233372000000000000
OK
127.0.0.1:6379> OBJECT encoding k1
"embstr"
8字節是64位,java裏long的範圍應該是
-9233372036854477808-9233372036854477808 (https://zhidao.baidu.com/question/256678932.html)
可是不知道爲何這裏redis彷佛不是
127.0.0.1:6379> set k1 呵 //length=3 OK 127.0.0.1:6379> object encoind k1 (error) ERR Syntax error. Try OBJECT (refcount|encoding|idletime) 127.0.0.1:6379> object encoding k1 "embstr" 127.0.0.1:6379> strlen k1 (integer) 3 127.0.0.1:6379> set k1 呵呵呵呵呵呵呵呵呵呵呵呵呵 //length=39 OK 127.0.0.1:6379> object encoding k1 "embstr" 127.0.0.1:6379> set k1 呵呵呵呵呵呵呵呵呵呵呵呵呵a //40 OK 127.0.0.1:6379> strlenth k1 (error) ERR unknown command 'strlenth' 127.0.0.1:6379> strlen k1 (integer) 40 127.0.0.1:6379> object encoding k1 "raw" 127.0.0.1:6379>
彷佛是1箇中文UTF-8佔3個字節的緣故
1.
hset key field value
het key field
127.0.0.1:6379> hset k1 f1 v1 (integer) 1 127.0.0.1:6379> hget k1 (error) ERR wrong number of arguments for 'hget' command 127.0.0.1:6379> hget k1 f1 "v1" 127.0.0.1:6379> HGETALL k1 1) "f1" 2) "v1" 127.0.0.1:6379>
2.hdel key field [...field]
127.0.0.1:6379> hset k1 f1 v1 (integer) 1 127.0.0.1:6379> hset k1 f2 v2 (integer) 1 127.0.0.1:6379> hset k1 f3 v3 (integer) 1 127.0.0.1:6379> hdel k1 f1 f2 //返回刪除個數 (integer) 2 127.0.0.1:6379> hget k1 (error) ERR wrong number of arguments for 'hget' command 127.0.0.1:6379> hgetall k1 1) "f3" 2) "v3" 127.0.0.1:6379>
3.hlen key返回field的個數
4.hmget field [field....]
hmset key field value [field value...]
批量操做hash
127.0.0.1:6379> hmset k1 f1 v1 f2 v2 f3 v3 OK 127.0.0.1:6379> mhget k1 f1 f2 f3 (error) ERR unknown command 'mhget' 127.0.0.1:6379> hmget k1 f1 f2 f3 1) "v1" 2) "v2" 3) "v3" 127.0.0.1:6379> HGETALL k1 1) "f1" 2) "v1" 3) "f2" 4) "v2" 5) "f3" 6) "v3" 127.0.0.1:6379>
5.
hexists key field 判斷field是否存在
127.0.0.1:6379> HEXISTS l1 f1 (integer) 0 127.0.0.1:6379> HEXISTS k1 f1 (integer) 1 127.0.0.1:6379> hget k1 f1 "v1" 127.0.0.1:6379> hget l1 f1 (nil) 127.0.0.1:6379>
6.
hkeys * 獲取全部field
hvals獲取全部value
hgetall key 獲取全部fieldvalue
127.0.0.1:6379> HKEYS k1 1) "f1" 2) "f2" 3) "f3" 127.0.0.1:6379> HVALS k1 1) "v1" 2) "v2" 3) "v3" 127.0.0.1:6379> HGETALL k1 1) "f1" 2) "v1" 3) "f2" 4) "v2" 5) "f3" 6) "v3" 127.0.0.1:6379>
7.
沒有hincr命令.hincrby和hincrbyfloat和hstrlen與String的相似
8.
hash的內部編碼有ziplist(個數小於512,或者全部值小於64字節),hashtable
一個列表最多能夠存儲2^32 -1 個元素.
lpush key value [value...]
rpush key value[value...]
127.0.0.1:6379> exists k1 (integer) 1 127.0.0.1:6379> del k1 (integer) 1 127.0.0.1:6379> lpush a b c (error) WRONGTYPE Operation against a key holding the wrong kind of value 127.0.0.1:6379> lpush k1 a b c (integer) 3 127.0.0.1:6379> rpush k1 d e f (integer) 6 127.0.0.1:6379> lrange k1 0 -1 1) "c" 2) "b" 3) "a" 4) "d" 5) "e" 6) "f" 127.0.0.1:6379> lrange k1 2 3 //取下標對應的元素,從0開始 1) "a" 2) "d" 127.0.0.1:6379>
linsert key before|after pivotValue value 在pivotValue以前或者以後插入元素
127.0.0.1:6379> lrange k1 0 -1 1) "c" 2) "b" 3) "a" 4) "d" 5) "e" 6) "f" 127.0.0.1:6379> 127.0.0.1:6379> LINSERT k1 before a 9 (integer) 7 127.0.0.1:6379> lrange k1 0 -1 1) "c" 2) "b" 3) "9" 4) "a" 5) "d" 6) "e" 7) "f" 127.0.0.1:6379> LINSERT k1 after a 8 (integer) 8 127.0.0.1:6379> lrange k1 0 -1 1) "c" 2) "b" 3) "9" 4) "a" 5) "8" 6) "d" 7) "e" 8) "f" 127.0.0.1:6379> lpush k1 a (integer) 9 127.0.0.1:6379> lrange k1 0 -1 1) "a" 2) "c" 3) "b" 4) "9" 5) "a" 6) "8" 7) "d" 8) "e" 9) "f" 127.0.0.1:6379> LINSERT k1 after a 7 //在找到的第一個元素後面添加而後直接return (integer) 10 127.0.0.1:6379> lrange k1 0 -1 1) "a" 2) "7" 3) "c" 4) "b" 5) "9" 6) "a" 7) "8" 8) "d" 9) "e" 10) "f" 127.0.0.1:6379> rINSERT k1 after a 7 //沒有rinsert (error) ERR unknown command 'rINSERT' 127.0.0.1:6379>
lindex key index 獲取指定位置的元素,負數就是從最後面1個元素開始數
127.0.0.1:6379> lrange k1 0 -1 1) "a" 2) "7" 3) "c" 4) "b" 5) "9" 6) "a" 7) "8" 8) "d" 9) "e" 10) "f" 127.0.0.1:6379> lindex k1 1 "7" 127.0.0.1:6379> lindex k1 -2 //倒數第二個元素 "e" 127.0.0.1:6379>
llen key獲取列表元素個數
lpop key和rpop key用於刪除元素
lrem key count value找到value之後最多刪除count個值爲value的元素
count>0纔可以左往右刪除,<0從右往左,=0所有刪除
127.0.0.1:6379> lrange k1 0 -1 1) "a" 2) "7" 3) "c" 4) "b" 5) "9" 6) "a" 7) "8" 8) "d" 9) "e" 10) "f" 127.0.0.1:6379> lrem k1 2 a //2個a都刪除了 (integer) 2 127.0.0.1:6379> lrange k1 0 -1 1) "7" 2) "c" 3) "b" 4) "9" 5) "8" 6) "d" 7) "e" 8) "f" 127.0.0.1:6379> lrem k1 8 -1 (integer) 0 127.0.0.1:6379> lrem k1 -1 8 //刪除1個8右邊開始 (integer) 1 127.0.0.1:6379> lrange k1 0 -1 1) "7" 2) "c" 3) "b" 4) "9" 5) "d" 6) "e" 7) "f" 127.0.0.1:6379> lrem k1 0 e //全部e都刪除 (integer) 1 127.0.0.1:6379> lrange k1 0 -1 1) "7" 2) "c" 3) "b" 4) "9" 5) "d" 6) "f" 127.0.0.1:6379>
ltrim key start end 按照索引保留元素
127.0.0.1:6379> exists k1 (integer) 1 127.0.0.1:6379> lrange k1 0 -1 1) "7" 2) "c" 3) "b" 4) "9" 5) "d" 6) "f" 127.0.0.1:6379> LTRIM k1 1 3 OK 127.0.0.1:6379> lrange k1 0 -1 1) "c" 2) "b" 3) "9" 127.0.0.1:6379>
lset key index newValue能夠修改index的元素
127.0.0.1:6379> lrange k1 0 -1 1) "c" 2) "b" 3) "9" 127.0.0.1:6379> lset k1 0 a OK 127.0.0.1:6379> lrange k1 0 -1 1) "a" 2) "b" 3) "9" 127.0.0.1:6379> lset k1 99 a (error) ERR index out of range 127.0.0.1:6379>
blpop key [key...] timeout 彈出key最左邊的元素,阻塞timeout秒.
brpop同理
127.0.0.1:6379> lrange k1 0 -1 1) "a" 2) "b" 3) "9" 127.0.0.1:6379> blpop k1 9 1) "k1" 2) "a" 127.0.0.1:6379> exists k2 (integer) 1 127.0.0.1:6379> del k2 (integer) 1 127.0.0.1:6379> del k2 (integer) 0 127.0.0.1:6379> blpop k2 9 (nil) (9.02s) 127.0.0.1:6379>
多個key只要有1個能返回就當即返回.
多個客戶端同時阻塞,添加元素後.哪一個客戶端命令先執行哪一個就先返回,剩下的繼續阻塞.
列表的內部實現有ziplist和linkedlist.條件範圍同hash
使用場景:
lpush和brpop能夠實現消息隊列.
集合不容許重複yuansu,zuiduo儲存2^32-1個元素.
sadd key element [element...] 新增元素
srem key element [element...] 刪除元素
scard key 計算元素個數(居然不是slen...)
smenbers key 返回集合全部元素
127.0.0.1:6379> exists k3 (integer) 1 127.0.0.1:6379> type k3 string 127.0.0.1:6379> get k3 "3vv\n" 127.0.0.1:6379> del k3 (integer) 1 127.0.0.1:6379> sadd k3 e1 e2 e3 e4 (integer) 4 127.0.0.1:6379> srem e2 e5 (integer) 0 127.0.0.1:6379> srem k3 e2 e5 //e2存在 e5不存在 (integer) 1 //成功刪除e2返回結果1 127.0.0.1:6379> scard k3 //返回集合元素個數爲3 (integer) 3 127.0.0.1:6379> SMEMBERS k3 //查看全部元素 1) "e1" 2) "e4" 3) "e3" 127.0.0.1:6379>
sismenmber key element 判斷元素是否在集合內
srandmember key [count] 隨機返回count個元素,默認爲1
spop 隨機彈出1個元素
127.0.0.1:6379> smembers k3 1) "e1" 2) "e4" 3) "e3" 127.0.0.1:6379> sismember k3 e1 //存在元素返回1 (integer) 1 127.0.0.1:6379> sismember k3 e2 //不存在返回0 (integer) 0 127.0.0.1:6379> sismember k3 e1 e2 (error) ERR wrong number of arguments for 'sismember' command 127.0.0.1:6379> sranmember key 1 (error) ERR unknown command 'sranmember' 127.0.0.1:6379> sranmember k3 1 (error) ERR unknown command 'sranmember' 127.0.0.1:6379> srandmember k3 1 //隨機返回1個元素不刪除 1) "e4" 127.0.0.1:6379> srandmember k3 1 1) "e1" 127.0.0.1:6379> srandmember k3 4 1) "e1" 2) "e4" 3) "e3" 127.0.0.1:6379> spop k3 //隨機返回1個元素並刪除 "e1" 127.0.0.1:6379> smembers (error) ERR wrong number of arguments for 'smembers' command 127.0.0.1:6379> smembers k3 1) "e4" 2) "e3" 127.0.0.1:6379> spop k3 9 //3.2之後支持 (error) ERR wrong number of arguments for 'spop' command 127.0.0.1:6379>
sinter key [key...] 取交集
sunion key [key...] 取並集
sdiff key [key..] 取差集
sinterstore destination key [keys...]
union和diff同理
127.0.0.1:6379> del k1 k2 k3 (integer) 3 127.0.0.1:6379> sadd k1 1 2 3 4 5 6 7 (integer) 7 127.0.0.1:6379> sadd k2 3 4 5 6 (integer) 4 127.0.0.1:6379> sadd k3 5 6 7 8 9 10 (integer) 6 127.0.0.1:6379> sinter k1 k2 1) "3" 2) "4" 3) "5" 4) "6" 127.0.0.1:6379> sinter k1 k2 k3 1) "5" 2) "6" 127.0.0.1:6379> sinterstore k4 k1 k2 k3 (integer) 2 127.0.0.1:6379> sdiff k1 k2 1) "1" 2) "2" 3) "7" 127.0.0.1:6379> sdiff k1 k2 k3 1) "1" 2) "2" 127.0.0.1:6379> SDIFFSTORE k6 k1 k2 k3 (integer) 2 127.0.0.1:6379>
集合內部使用intset或者hashtable實現
intset爲集合全部元素都爲整形或者元素小於等於512個時候
hashtable爲不知足intset的時候
場景
能夠用於用戶標籤
有序集合保留了集合不能有重複元素的特徵,可是能夠排序,每一個元素都有個對應的分數做爲排序依據(分數能夠重複).
zadd key score member [score member...] 添加元素
zcard key 計算元素個數
zscore key member 計算元素的分數
127.0.0.1:6379> del k1 (integer) 1 127.0.0.1:6379> zadd k1 1 e1 2 e2 3 e3 4 e4 5 e5 (integer) 5 127.0.0.1:6379> zcard k1 (integer) 5 127.0.0.1:6379> zscore k1 e3 "3" 127.0.0.1:6379>
zrank key member [member...] 和 zrevrank key member 對元素進行排序輸出排序好嗎,從0開始
zrem key remember [member...] 對元素進行刪除
zincrby key incrememt member 增長成員的分數
127.0.0.1:6379> zrem k1 e2 (integer) 1 127.0.0.1:6379> zrank k1 e1 (integer) 0 127.0.0.1:6379> zrevrank k1 e1 (integer) 3 127.0.0.1:6379> ZINCRBY k1 99 e1 "100" 127.0.0.1:6379> zrevrank k1 e1 (integer) 0 127.0.0.1:6379> zrank k1 e1 (integer) 3 127.0.0.1:6379>
zrange key start end [withscores] 低到高排序輸出start-end的元素
zrevrange key start end [withscores] 高到低排序輸出元素
127.0.0.1:6379> zrange k1 0 -1 // 輸出全部元素 -1是最後1個 0是第一個 1) "e3" 2) "e4" 3) "e5" 4) "e1" 127.0.0.1:6379> zrange k1 0 0 1) "e3" 127.0.0.1:6379> zrange k1 0 -3 1) "e3" 2) "e4" 127.0.0.1:6379> zrange k1 1 1 1) "e4" 127.0.0.1:6379> zrange k1 0 -1 withscores 1) "e3" 2) "3" 3) "e4" 4) "4" 5) "e5" 6) "5" 7) "e1" 8) "100" 127.0.0.1:6379> zrevrange k1 0 -1 withscores 1) "e1" 2) "100" 3) "e5" 4) "5" 5) "e4" 6) "4" 7) "e3" 8) "3" 127.0.0.1:6379>
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offser count]
返回指定分數範圍內的成員
127.0.0.1:6379> zrange k1 0 -1 withscores 1) "e3" 2) "3" 3) "e4" 4) "4" 5) "e5" 6) "5" 7) "e1" 8) "100" 127.0.0.1:6379> 127.0.0.1:6379> zrangebyscore k1 0 999 withscores 1) "e3" 2) "3" 3) "e4" 4) "4" 5) "e5" 6) "5" 7) "e1" 8) "100" 127.0.0.1:6379> zrangebyscore k1 0 +inf withscores //+inf表示無限大 1) "e3" 2) "3" 3) "e4" 4) "4" 5) "e5" 6) "5" 7) "e1" 8) "100" 127.0.0.1:6379> zrangebyscore k1 (3 +inf withscores //默認是[閉區間 (表示開區間 1) "e4" 2) "4" 3) "e5" 4) "5" 5) "e1" 6) "100" 127.0.0.1:6379> zrangebyscore k1 {3 +inf withscores (error) ERR min or max is not a float 127.0.0.1:6379> zrangebyscore k1 [3 +inf withscores //彷佛不能是[ (error) ERR min or max is not a float 127.0.0.1:6379> zrangebyscore k1 3 -inf withscores (empty list or set) 127.0.0.1:6379> zrangebyscore k1 3 2 withscores (empty list or set) 127.0.0.1:6379> ZREVRANGEBYSCORE k1 +inf 0 withscores //reverse的時候先寫max再寫min 1) "e1" 2) "100" 3) "e5" 4) "5" 5) "e4" 6) "4" 7) "e3" 8) "3" 127.0.0.1:6379> ZREVRANGEBYSCORE k1 (100 0 withscores 1) "e5" 2) "5" 3) "e4" 4) "4" 5) "e3" 6) "3" 127.0.0.1:6379> ZREVRANGEBYSCORE k1 (100 101 withscores (empty list or set) 127.0.0.1:6379>
zcount key min max 返回分數範圍內成員個數
zremrangebyzrank key start end 刪除元素,按升序
zremrangebyscore key min max 刪除元素按分數
127.0.0.1:6379> zcount k1 50 +inf (integer) 1 127.0.0.1:6379> ZRANK k1 0 -1 (error) ERR wrong number of arguments for 'zrank' command 127.0.0.1:6379> zrange k1 0 -1 1) "e3" 2) "e4" 3) "e5" 4) "e1" 127.0.0.1:6379> zrange k1 0 -1 withscores 1) "e3" 2) "3" 3) "e4" 4) "4" 5) "e5" 6) "5" 7) "e1" 8) "100" 127.0.0.1:6379> ZREMRANGEBYRANK k1 0 1 (integer) 2 127.0.0.1:6379> zrange k1 0 -1 withscores 1) "e5" 2) "5" 3) "e1" 4) "100" 127.0.0.1:6379> ZREMRANGEBYSCORE k1 0 5 (integer) 1 127.0.0.1:6379> zrange k1 0 -1 withscores 1) "e1" 2) "100" 127.0.0.1:6379>
zinterstore destnation numkeys key [key...] [weights weight [weight....]] [aggragate sum|min|max] 計算交集
127.0.0.1:6379> del k1 (integer) 1 127.0.0.1:6379> ZADD k1 10 e1 20 e2 30 e3 40 e4 50 e5 (integer) 5 127.0.0.1:6379> del k2 (integer) 1 127.0.0.1:6379> ZADD k2 11 e1 22 e2 33 e3 44 e4 55 e5 (integer) 5 127.0.0.1:6379> zadd k2 66 e6 (integer) 1 127.0.0.1:6379> ZINTERSTORE k1_2 2 k1 k2 (integer) 5 127.0.0.1:6379> zrange k1_2 0 -1 1) "e1" 2) "e2" 3) "e3" 4) "e4" 5) "e5" 127.0.0.1:6379> zrange k1_2 0 -1 withscores 1) "e1" 2) "21" 3) "e2" 4) "42" 5) "e3" 6) "63" 7) "e4" 8) "84" 9) "e5" 10) "105" 127.0.0.1:6379> ZINTERSTORE k1_2 2 k1 k2 weights 0.5 1 (integer) 5 127.0.0.1:6379> zrange k1_2 0 -1 withscores //默認是weight都是1,aggregate是sum 1) "e1" 2) "16" 3) "e2" 4) "32" 5) "e3" 6) "48" 7) "e4" 8) "64" 9) "e5" 10) "80" 127.0.0.1:6379> ZINTERSTORE k1_2 2 k1 k2 weights 0.3 //weights寫了1個就必須都得寫完 (error) ERR syntax error 127.0.0.1:6379> ZINTERSTORE k1_2 2 k1 k2 weights 0.3 1 (integer) 5 127.0.0.1:6379> zrange k1_2 0 -1 withscores 1) "e1" 2) "14" 3) "e2" 4) "28" 5) "e3" 6) "42" 7) "e4" 8) "56" 9) "e5" 10) "70" 127.0.0.1:6379> ZINTERSTORE k1_2 2 k1 k2 weights 0.5 0.5 (integer) 5 127.0.0.1:6379> zrange k1_2 0 -1 withscores 1) "e1" 2) "10.5" 3) "e2" 4) "21" 5) "e3" 6) "31.5" 7) "e4" 8) "42" 9) "e5" 10) "52.5" 127.0.0.1:6379> ZINTERSTORE k1_2 2 k1 k2 weights 1 1 aggragate min (error) ERR syntax error 127.0.0.1:6379> ZINTERSTORE k1_2 2 k1 k2 weights 1 1 aggregate min (integer) 5 127.0.0.1:6379> zrange k1_2 0 -1 withscores 1) "e1" 2) "10" 3) "e2" 4) "20" 5) "e3" 6) "30" 7) "e4" 8) "40" 9) "e5" 10) "50" 127.0.0.1:6379>
zunionstore destination numkeys key [key...] [weights weight [weight...]] [aggregate sum|min|max] 計算並集
127.0.0.1:6379> clear 127.0.0.1:6379> zrange k1 0 -1 withscores 1) "e1" 2) "10" 3) "e2" 4) "20" 5) "e3" 6) "30" 7) "e4" 8) "40" 9) "e5" 10) "50" 127.0.0.1:6379> zrange k2 0 -1 withscores 1) "e1" 2) "11" 3) "e2" 4) "22" 5) "e3" 6) "33" 7) "e4" 8) "44" 9) "e5" 10) "55" 11) "e6" 12) "66" 127.0.0.1:6379> zunoin k1_2 2 k1 k2 weights 1 0.5 (error) ERR unknown command 'zunoin' 127.0.0.1:6379> zunion k1_2 2 k1 k2 weights 1 0.5 (error) ERR unknown command 'zunion' 127.0.0.1:6379> zunionstore k1_2 2 k1 k2 weights 1 0.5 (integer) 6 127.0.0.1:6379> zrange k1_2 0 -1 WITHSCORES 1) "e1" 2) "15.5" 3) "e2" 4) "31" 5) "e6" 6) "33" 7) "e3" //e6只有33由於k1裏沒有,k2 weight是0.5 8) "46.5" 9) "e4" 10) "62" 11) "e5" 12) "77.5" 127.0.0.1:6379>
內部使用ziplist和skiplist.
元素個數小於128而且只都小於64字節時用ziplist不然用skiplist
場景
主要用於排行榜
rename key newKey 重命名鍵
renamenx key newKey 當newkey不存在的時候纔會成功重命名
randomkey 隨機返回1個鍵
127.0.0.1:6379> del k1 k2 (integer) 2 127.0.0.1:6379> mset k1 haha k2 hehe OK 127.0.0.1:6379> mget k1 k2 1) "haha" 2) "hehe" 127.0.0.1:6379> rename k1 k2 OK 127.0.0.1:6379> exists k1 (integer) 0 127.0.0.1:6379> exists k2 (integer) 1 127.0.0.1:6379> get k2 "haha" 127.0.0.1:6379> rename k2 k2 //同樣的key在3.2如下版本會boom (error) ERR source and destination objects are the same 127.0.0.1:6379> keys * 1) "e" 2) "k2" 3) "b" 4) "k4" 5) "f" 6) "h" 7) "k6" 8) "k3" 9) "d" 10) "g" 11) "k1_2" 12) "c" 13) "a" 127.0.0.1:6379> RANDOMKEY "k4" 127.0.0.1:6379> RANDOMKEY "k4" 127.0.0.1:6379> RANDOMKEY "a" 127.0.0.1:6379> RANDOMKEY "k4" 127.0.0.1:6379> RANDOMKEY "b" 127.0.0.1:6379>
expire key seconds 設置X秒後鍵過時,負數直接刪除
expireat key timestamp 在秒級時間戳後x後過時
ttl key 返回鍵的剩餘過時秒數
persist 清除鍵過時時間
127.0.0.1:6379> exists k2 (integer) 1 127.0.0.1:6379> ttl k2 (integer) -1 // -1不過時 127.0.0.1:6379> expire k2 999 (integer) 1 127.0.0.1:6379> ttl k2 (integer) 997 127.0.0.1:6379> PERSIST k2 //永不過時 (integer) 1 127.0.0.1:6379> ttl k2 (integer) -1 127.0.0.1:6379> get k2 "haha" 127.0.0.1:6379> del k2 (integer) 1 127.0.0.1:6379> ttl k2 (integer) -2 // -2鍵不存在 127.0.0.1:6379>
pexpire key milliseconds 設置鍵X毫秒後撿國旗
pexpireat key milliseconds-timestamp 在毫秒級時間戳X後鍵過時
set會去除過時時間
127.0.0.1:6379> set k1 heihei ex 999 OK 127.0.0.1:6379> get k1 "heihei" 127.0.0.1:6379> ttl k1 (integer) 994 127.0.0.1:6379> ttl k1 (integer) 993 127.0.0.1:6379> set k1 wahaha OK 127.0.0.1:6379> ttl k1 (integer) -1 // 時間被清除了 127.0.0.1:6379>
redis不支持對二級數據結構作過時時間設置
setex命令是原子執行的
move能夠在redis內部數據庫進行鍵遷移
127.0.0.1:6379> select 0 OK 127.0.0.1:6379> get k1 "wahaha" 127.0.0.1:6379> move k1 1 (integer) 1 127.0.0.1:6379> exists k1 (integer) 0 127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> keys * 1) "k1" 127.0.0.1:6379[1]> get k1 "wahaha" 127.0.0.1:6379[1]>
dump key 將值序列化
restore key ttl value 將值反序列化到數據庫中
127.0.0.1:6379> exists k1 (integer) 1 127.0.0.1:6379> type k1 string 127.0.0.1:6379> dump l1 (nil) 127.0.0.1:6379> dump k1 "\x00\x06wahaha\x06\x00\xd7\x03\xb2\xb3I5\xd9\xc7" 127.0.0.1:6379>
127.0.0.1:6380> RESTORE k1 0 "\x00\x06wahaha\x06\x00\xd7\x03\xb2\xb3I5\xd9\xc7" OK 127.0.0.1:6380> get k1 "wahaha" 127.0.0.1:6380>
migrate host port key| "" destination-db timeout [copy] [replace] [keys key [key ...]] 在redis以前遷移數據,migrate命令具備原子性
127.0.0.1:6379> keys * 1) "e" 2) "b" 3) "k4" 4) "k1" 5) "f" 6) "h" 7) "k6" 8) "k3" 9) "d" 10) "g" 11) "k1_2" 12) "c" 13) "a" 127.0.0.1:6379> MIGRATE localhost 6379 0 0 copy replace e b k4 k1 f h k6 k3 d g k1_2 c a (error) ERR syntax error 127.0.0.1:6379> MIGRATE localhost 6380 0 0 copy replace e b k4 k1 f h k6 k3 d g k1_2 c a (error) ERR syntax error 127.0.0.1:6379> MIGRATE localhost 6380 0 1000 copy replace e b k4 k1 f h k6 k3 d g k1_2 c a (error) ERR syntax error 127.0.0.1:6379> MIGRATE 127.0.0.1 6380 0 0 copy replace e b k4 k1 f h k6 k3 d g k1_2 c a (error) ERR syntax error 127.0.0.1:6379> MIGRATE localhost 6380 0 0 copy replace keys e b k4 k1 f h k6 k3 d g k1_2 c a (error) ERR When using MIGRATE KEYS option, the key argument must be set to the empty string 127.0.0.1:6379> MIGRATE localhost 6380 "" 0 0 copy replace keys e b k4 k1 f h k6 k3 d g k1_2 c a //不要忘記寫"" OK 127.0.0.1:6379>
127.0.0.1:6380> keys * 1) "k1_change" 127.0.0.1:6380> del k1_change (integer) 1 127.0.0.1:6380> keys * (empty list or set) //等待6379遷移數據過來 127.0.0.1:6380> keys * 1) "k4" 2) "c" 3) "b" 4) "k3" 5) "e" 6) "a" 7) "k6" 8) "k1_2" 9) "h" 10) "d" 11) "k1" 12) "f" 13) "g" 127.0.0.1:6380>
不知道爲何我1個redis實例不一樣數據庫之間遷移不行,我以爲多是由於這是1個事務,同個實例要接受遷移的鍵也要等這個事務結束才行.因此遷移須要等待接受好才能結束,接受須要等遷移事務結束才能夠開始形成的.(猜想)
127.0.0.1:6379> MIGRATE localhost 6379 "" 1 0 copy replace keys e b k4 k1 f h k6 k3 d g k1_2 c a (error) IOERR error or timeout reading to target instance (1.00s) 127.0.0.1:6379> MIGRATE localhost 6379 "" 1 3000 copy replace keys e b k4 k1 f h k6 k3 d g k1_2 c a (error) IOERR error or timeout reading to target instance (3.00s) 127.0.0.1:6379>
遷移命令比較
命令 | 做用域 | 原子性 | 支持多個鍵 |
move | redis實例內部 | 是 | 否 |
dump+restore | redis實例之間 | 否 | 否 |
migrate | redis實例之間 | 是 | 是 |
keys pattern 遍歷鍵
*表明任意字符
?表明一個字符
[]表明部分匹配,[1,3]表明匹配1,3 [1-10]表明匹配1-10任意數字
\x用來轉義
127.0.0.1:6380> exists ka1 (integer) 1 127.0.0.1:6380> keys k[a-z]1 1) "ka1" 127.0.0.1:6380> k?[1-99] (error) ERR unknown command 'k?[1-99]' 127.0.0.1:6380> k?[0-10] (error) ERR unknown command 'k?[0-10]' 127.0.0.1:6380> k?[1-10] (error) ERR unknown command 'k?[1-10]' 127.0.0.1:6380> keys k?[0-99] 1) "ka1" 127.0.0.1:6380>
刪除鍵
redis-cli keys pattern | xargs redis-cli del //我執行是失敗的,不認識xargs....
漸進式遍歷鍵
scan cursor [match pattern] [count number]
cursor是遊標,從0開始,count number默認是10,命令返回當前遊標值
127.0.0.1:6380> mset a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q qr r s s t t u u v v w w x x y y z z (error) ERR wrong number of arguments for MSET 127.0.0.1:6380> mset a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z OK 127.0.0.1:6380> scan 0 1) "22" 2) 1) "y" 2) "g" 3) "o" 4) "z" 5) "s" 6) "e" 7) "i" 8) "h" 9) "a" 10) "t" 127.0.0.1:6380> scan 22 1) "7" 2) 1) "b" 2) "j" 3) "k" 4) "q" 5) "d" 6) "m" 7) "r" 8) "n" 9) "p" 10) "x" 11) "f" 127.0.0.1:6380> scan 7 1) "0" 2) 1) "v" 2) "l" 3) "u" 4) "w" 5) "c" 127.0.0.1:6380>
注意第二次返回了11個元素
SCAN 命令的保證(guarantees)
SCAN 命令, 以及其餘增量式迭代命令, 在進行完整遍歷的狀況下能夠爲用戶帶來如下保證: 從完整遍歷開始直到完整遍歷結束期間, 一直存在於數據集內的全部元素都會被完整遍歷返回; 這意味着, 若是有一個元素, 它從遍歷開始直到遍歷結束期間都存在於被遍歷的數據集當中, 那麼 SCAN 命令總會在某次迭代中將這個元素返回給用戶。
然而由於增量式命令僅僅使用遊標來記錄迭代狀態, 因此這些命令帶有如下缺點:
- 同一個元素可能會被返回屢次。 處理重複元素的工做交由應用程序負責, 好比說, 能夠考慮將迭代返回的元素僅僅用於能夠安全地重複執行屢次的操做上。
- 若是一個元素是在迭代過程當中被添加到數據集的, 又或者是在迭代過程當中從數據集中被刪除的, 那麼這個元素可能會被返回, 也可能不會, 這是未定義的(undefined)。
SCAN 命令每次執行返回的元素數量
增量式迭代命令並不保證每次執行都返回某個給定數量的元素。
增量式命令甚至可能會返回零個元素, 但只要命令返回的遊標不是 0 , 應用程序就不該該將迭代視做結束。
不過命令返回的元素數量老是符合必定規則的, 在實際中:
- 對於一個大數據集來講, 增量式迭代命令每次最多可能會返回數十個元素;
- 而對於一個足夠小的數據集來講, 若是這個數據集的底層表示爲編碼數據結構(encoded data structure,適用因而小集合鍵、小哈希鍵和小有序集合鍵), 那麼增量迭代命令將在一次調用中返回數據集中的全部元素。
最後, 用戶能夠經過增量式迭代命令提供的 COUNT 選項來指定每次迭代返回元素的最大值。
COUNT 選項
雖然增量式迭代命令不保證每次迭代所返回的元素數量, 但咱們可使用 COUNT 選項, 對命令的行爲進行必定程度上的調整。
基本上, COUNT 選項的做用就是讓用戶告知迭代命令, 在每次迭代中應該從數據集裏返回多少元素。
雖然 COUNT 選項只是對增量式迭代命令的一種提示(hint), 可是在大多數狀況下, 這種提示都是有效的。
- COUNT 參數的默認值爲 10 。
- 在迭代一個足夠大的、由哈希表實現的數據庫、集合鍵、哈希鍵或者有序集合鍵時, 若是用戶沒有使用 MATCH 選項, 那麼命令返回的元素數量一般和 COUNT 選項指定的同樣, 或者比 COUNT 選項指定的數量稍多一些。
- 在迭代一個編碼爲整數集合(intset,一個只由整數值構成的小集合)、 或者編碼爲壓縮列表(ziplist,由不一樣值構成的一個小哈希或者一個小有序集合)時, 增量式迭代命令一般會無視 COUNT 選項指定的值, 在第一次迭代就將數據集包含的全部元素都返回給用戶。
並不是每次迭代都要使用相同的 COUNT 值。
用戶能夠在每次迭代中按本身的須要隨意改變 COUNT 值, 只要記得將上次迭代返回的遊標用到下次迭代裏面就能夠了。
http://doc.redisfans.com/key/scan.html
select index 切換數據庫
建議使用多個實例,只是用數據庫0.由於1個實例多個數據庫也是共享1個CPU的.
flushdb 清除當前數據庫數據
flushall 清除全部數據庫數據