## 一、通用命令
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| keys | keys ( * ) | 遍歷(獲取)所有 正則匹配的key |
| dbsize | dbsize ( ) | 計算key的總數 |
| exists | exists( $key ) | 檢查key是否存在 |
| del | del( $key1, $key2 = null, $key3 = null ) | 刪除指定key-value |
| expire | expire( $key, $ttl ) | key 在 ttl 秒后過期 |
| ttl | ttl( $key ) | 查看 key 剩余的過期時間 |
| persist | persist ( $key ) | 去掉 key 的過期時間,永生 |
| type | type($key) | 返回 key 的類型 |
## 二、數據結構和內部編碼
## 三、單線程
* 一次只運行一條命令
* 拒絕長(慢)命令
* keys,flushall,flushdb,slow lua script , mutil/exec , operate big value( collection )
* 其實不是單線程
* fysnc file descriptor
* close file descriptor
* 單線程為什么這么快?
* 純內存
* 非阻塞IO
* 避免線程切換和競態消耗
## 四、字符串
* 字符串鍵值結構
* string類型是二進制安全的。意思是redis的string可以包含任何數據。比如jpg圖片或者序列化的對象 。
* 一個鍵最大能存儲512MB
* 場景
* 緩存 (用戶信息,需要序列化)
* 計數器(網站訪問量、點擊量)
* 分布式鎖(分布式自增ID,例如有三個 service 并發去獲取 ,每次獲取到的ID是自增的唯一的。利用到了redis的單線程和原子性 )
* 命令
| 名稱 | 范例 | 說明 |
| --- | --- | --- |
| * get | get( $key ) | 獲取 key 對應的 value |
| * set | set( $key, $value, $timeout = 0 ) | 設置 key - value 和 過期時間 timeout |
| * del | del( $key1, $key2 = null, $key3 = null ) | 刪除key |
| * incr | incr( $key ) | key 自增 1,如果key 不存在,自增后 get(key)=1|
| * decr | decr( $key ) | key 自減 1,如果key 不存在,自減后get(key)=-1 |
| incrby | incrBy( $key, $value ) | key 自增 value,如果 key 不存在,自增后get(key)= value |
| decrby | decrBy( $key, $value ) | key 自減 value,如果key不存在,自減后 get(key)= - value |
| * mget | mget( array $array ) | 批量獲取key ,原子操作 |
| * mset | mset( array $array ) | 批量設置 key - value |
| getset | getSet( $key, $value ) | set key NewValue并返回舊的value |
| append | append( $key, $value ) | 將 value 追加到舊的 value |
| strlen | strlen( $key ) | 返回字符串的長度(注意中文 ) |
| incrbyfloat | incrByFloat( $key, $increment ) | 增加 key 對應的值 ,例:3.5 |
| getrange | getRange( $key, $start, $end ) | 獲取字符串指定下標所有的值 |
| setrange | setRange( $key, $offset, $value ) | 設置指定下標所有對應的值 |
## 五、哈希
* 哈希鍵值結構

* 每一個field都是單獨的屬性,可以進行添加刪除更改。
* key 可以看作一張關系表的一行,field是其中的列或者屬性。
* field不能相同
* 命令
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| hget | hGet($key, $hashKey) | 獲取 key 對應的 hashKey 的 value |
| hset | hSet( $key, $hashKey, $value ) | 設置 key 對應的 hashKey 的value |
| hdel | hDel( $key, $hashKey1, $hashKey2 = null, $hashKeyN = null ) | 刪除 key 對應的 hashKey 的value |
| hexists | hExists( $key, $hashKey ) | 判斷 key 是否有 hashKey |
| hlen | hLen( $key ) | 獲取 key 的 hashKey的數量 |
| hmget | hMGet( $key, $hashKeys ) | 批量獲取 key 的一批 hashKeys對應的值 |
| hmset | hMset( $key, $hashKeys ) | 批量設置 key 的一批 hashKeys對應的值 |
| hgetall | hGetAll( $key ) | 返回 key 對應所有的 hashKey 和 value |
| hvals | hVals( $key ) | 返回 key 對應所有 hashKey 的 value |
| hkeys | hKeys( $key ) | 返回 key 對應所有 hashKey |
* 實戰
* 記錄網站每個用戶個人主頁的訪問量?
* 緩存視頻的基本信息
* string需要進行序列化和反序列號,更新操作時開銷大
* hash 存儲時可以針對某個值進行更新,開銷小
* 3種方案比較
| 命令 | 優點 | 缺點 |
| --- | --- | --- |
| string v1 <br>(序列化為json或其他格式) | 編程簡單 <br> 可能節約內存 | 1.序列化開銷 <br> 2.設置屬性要操作整個數據。 |
| string v2 <br>(每個key都是一個屬性 ) | 直觀<br> 可以部分更新 | 1.內存占用較大 <br> 2.key較為分散 |
| hash | 直觀 <br> 節省空間 <br> 可以部分更新 | 1.編程稍微復雜 <br> 2.ttl不好控制 |
* 查漏補缺
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| hsetnx | hSetNx( $key, $hashKey, $value ) | 設置 key 對應 hashKey 的 value(如 hashKey 已經存在,則失敗) |
| hincrby | hIncrBy( $key, $hashKey, $value ) | hashKey 自增 value,如果 hashKey 不存在,自增后hget(key,hashKey)= value |
| hincrbyfloat | hIncrByFloat( $key, $field, $increment ) | hincrby 浮點數版 |
## 六、列表
* 列表結構
* 特點
* 有序的
* 可以重復的
* 左右兩邊插入彈出
* 命令
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| rpush | rPush( $key, $value1, $value2 = null, $valueN = null ) | 從列表右端插入值(1-N) |
| lpush | lPush( $key, $value1, $value2 = null, $valueN = null ) | 從列表左端插入值(1-N) |
| linsert | lInsert( $key, $position, $pivot, $value ) | 在 list 指定的值($pivot)前\|后($position = Redis::BEFORE\|Redis::AFTER)插入newValue($value) |
| lpop | lPop( $key ) | 從列表左側彈出一個itme |
| rpop | rPop( $key ) | 從列表右側彈出一個itme |
| lrem | lRem( $key, $value, $count ) | 根據 count 值,從列表中刪除所有 value 相等的項。 <br> count > 0 , 從左到右,刪除最多 count 個 value 相等的項; <br> count < 0 , 從右到左,刪除最多Math.abs(count) 個 value 相等的項; <br> count = 0 , 刪除所有value相等的項。 |
| ltrim | lTrim( $key, $start, $stop ) | 按照索引范圍修剪列表,key值中保留從start 到stop 范圍的下標 |
* 查詢
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| lrange | lRange( $key, $start, $end ) | 獲取列表指定索引范圍所有 item |
| lindex | lIndex( $key, $index ) | 獲取列表指定索引的 item |
| llen | lLen( $key ) | 獲取列表長度 |
* 改
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| lset | lSet( $key, $index, $value ) | 設置列表指定索引為 value |
* 實戰
* 更新微博的排列順序,有人更新的時候,把他的微博排在首位。
* 查漏補缺
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| blpop | blPop( array $keys ) | lpop阻塞版本,timeout是阻塞超時時間,timeout = 0 為永遠不阻塞 |
| brpop | brPop( array $keys ) | rpop阻塞版本,timeout是阻塞超時時間,timeout = 0為永遠不阻塞 |
* 總結
* 棧功能:lrush + lpop = stack
* 隊列功能: lpush + rpop = queue
* 控制有固定數量的列表: lpush + ltrim = Capped Collection
* 消息隊列: Lpush + brpop = Message Queue
## 集合
* 特點
* 無序的
* 無重復
* 集合間操作
* 集合內的命令
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| sadd | sAdd( $key, $value1, $value2 = null, $valueN = null ) | 向集合key添加 value (如果value已存在,添加失敗) |
| srem | sRem( $key, $member1, $member2 = null, $memberN = null ) | 將集合key 中的 member 移除掉 |
| srcard | sCard( $key ) | 計算集合大小 |
| sismember | sIsMember( $key, $value ) | 判斷 value 是否在集合中 |
| srandmember | sRandMember( $key ) | 從集合中隨機取出一個元素,不破環原集合 |
| spop | sPop( $key ) | 從集合中隨機取出一個元素,并從原集合消失 |
| smembers | sMembers( $key ) | 從集合中隨機彈出一個元素,返回剩余的元素 |
* 集合內實戰
* 抽獎系統
* 給用戶添加標簽tag
* 給標簽添加用戶
* Like、贊、踩都可以放在集合中
* 集合間的命令
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| sdiff | sDiff( $key1, $key2, $keyN = null ) | 差集 |
| sinter | sInter( $key1, $key2, $keyN = null ) | 交集 |
| sunion | sUnion( $key1, $key2, $keyN = null ) | 并集 |
* 集合間的實戰
* 共同關注的好友或興趣
* 總結
* SADD = Tagging 標簽
* SPOP/SRANDMEMBER = Random item 隨機數
* SADD + SINTER = Social Graph 社交相關的應用
## 有序集合
* 結構

* 集合 VS 有序集合
| 集合 | 有序集合 |
| --- | --- |
| 無重復元素 | 無重復元素 |
| 無序 | 有序 |
| element(集合內元素) | element(集合內元素) + score(分值) |
* 列表 VS 有序集合
| 列表 | 有序集合 |
| --- | --- |
| 可以有重復元素 | 無重復元素 |
| 有序 | 有序 |
| element | element + score |
* 命令
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| zadd | zAdd( $key, $score1, $value1, $score2 = null, $value2 = null, $scoreN = null, $valueN = null ) | 添加score 和 value |
| zrem | zRem( $key, $member1, $member2 = null, $memberN = null ) | 刪除元素 |
| zscore | zScore( $key, $member ) | 返回元素的分值,升序,從低到高 |
| zincrby | zIncrBy( $key, $value, $member ) | 增加或減少元素的分值 |
| zcard | zCard( $key ) | 返回元素的總個數 |
| zrange | zRange( $key, $start, $end, $withscores = null ) | 返回指定索引范圍內的升序元素,$withscores = ture 返回分值 |
| zrangebyscore | zRangeByScore( $key, $start, $end, array $options = array() ) | 返回指定分值范圍內的升序元素,$options = array('withscores' => TRUE, 'limit' => array(1, 1)) |
| zcount | zCount( $key, $start, $end ) | 返回有序集合內在指定分數范圍內的個數 |
| zremrangebyrank | zRemRangeByRank( $key, $start, $end ) | 刪除指定排名內的升序元素 |
| zremrangebyscore | zDeleteRangeByRank( $key, $start, $end ) | 刪除指定分數內的升序元素 |
* 實戰
* 排行榜
* 查漏補缺
| 名稱 | 范例 | 描述 |
| --- | --- | --- |
| zrevrank | zRevRank( $key, $member ) | 返回元素的分值,降序,從高到地。|
| zrevrange | zRevRange( $key, $start, $end, $withscore = null ) | 返回指定索引范圍內的降序元素,$withscores = ture 返回分值 |
| zrevrangebyscore | zRevRangeByScore( $key, $start, $end, array $options = array() ) | 返回指定分值范圍內的降序元素,$options = array('withscores' => TRUE, 'limit' => array(1, 1)) |
| zinterstore | zInter($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM') | 交集 |
| zunionstore | zUnion($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM') | 并集 |
* 總結
| 操作類型 | 命令 |
| --- | --- |
| 基本操作 | zadd、zrem、zcard、zincrby、zscore |
| 范圍操作 | zrange、zrangebyscore、zcount、zremrangebyrank|
| 集合操作 | zunionstore、zinterstore |