1、安裝Redis
Redis6.0在2020年已經發布,所以我們安裝Redis3.0,😂
1.1、在Linux上安裝Redis
我們在CentOS上安裝Redis,常見的的有三種安裝方式:
- yum/apt軟體管理軟體安裝
- 原始碼的方式進行安裝
- 容器化安裝
我們這里選擇第二種方式:
- 1)下載Redis指定版本的原始碼壓縮包到當前目錄
wget http://download.redis.io/releases/redis-3.0.7.tar.gz
- 2)解壓縮Redis原始碼壓縮包
tar xzf redis-3.0.7.tar.gz
- 3)建立一個redis目錄的軟連接,指向redis-3.0.7
ln -s redis-3.0.7 redis
- 4)進入redis目錄
cd redis
- 5)編譯(編譯之前確保作業系統已經安裝gcc)
make
- 6)安裝
make install
最后可以執行redis-cli–v查看Redis的版本

1.2、啟動Redis
有三種方法啟動Redis:默認配置、運行配置、組態檔啟動,
我們這里用默認配置的方式啟動Redis:
redis-server

一般在生產環境會使用組態檔啟動的方式,
1.3、Redis命令列客戶端
Redis服務已經啟動,現在使用redis-cli來連接,
redis-cli -h 127.0.0.1 -p 6379

2、Redis基本資料結構
Redis 有 5 種基礎資料結構,分別為:string (字串)、list (串列)、set (集合)、hash (哈希) 和 zset (有序集合),

2.1、字串
字串型別是Redis最基礎的資料結構,所有的鍵都是字串型別,
Redis 所有的資料結構都是以唯一的 key 字串作為名稱,然后通過這個唯一 key 值來獲取相應的 value 資料,不同型別的資料結構的差異就在于 value 的結構不一樣,

而且其他幾種資料結構都是在字串型別基礎上構建的,所以字串型別能為其他四種資料結構的學習奠定基礎,
除了上圖描述簡單的字串,字串型別的值也可以是復雜的字串(例如JSON、XML)、數字 (整數、浮點數),甚至是二進制(圖片、音頻、視頻),但是值最大不能 超過512MB,

2.1.1、命令
- 設定值
set key value [ex seconds] [px milliseconds] [nx|xx]
下面操作設定鍵為Hello,值為World的鍵值對,回傳結果為OK代表設定成功:
127.0.0.1:6379> set Hello World
OK
set命令有幾個選項:
-
ex seconds:為鍵設定秒級過期時間,
-
px milliseconds:為鍵設定毫秒級過期時間,
-
nx:鍵必須不存在,才可以設定成功,用于添加,
-
xx:與nx相反,鍵必須存在,才可以設定成功,用于更新,
-
獲取值
get key
下面操作獲取鍵Hello的值:
127.0.0.1:6379> get Hello
"World"
如果要獲取的鍵不存在,則回傳nil(空):
127.0.0.1:6379> get some
(nil)
- 批量設定值
mset key value [key value ...]
可以批量對多個字串進行讀寫,節省網路耗時開銷,
下面操作通過mset命令一次性設定4個鍵值對:
127.0.0.1:6379> mset a 1 b 2 c 3 d 4
OK
- 批量獲取值
mget key [key ...]
下面操作批量獲取了鍵a、b、c、d的值:
127.0.0.1:6379> mget a b c d
1) "1"
2) "2"
3) "3"
4) "4"
- 計數
incr key
incr命令用于對值做自增操作,回傳結果分為三種情況:
-
值不是整數,回傳錯誤,
-
值是整數,回傳自增后的結果,
-
鍵不存在,按照值為0自增,回傳結果為1,
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> incr age
(integer) 19
除了incr命令,Redis提供了decr(自減)、incrby(自增指定數字)、 decrby(自減指定數字)、incrbyfloat(自增浮點數),
2.1.2、應用場景
字串可以說是Redis應用最廣泛的資料結構,我們來看一下在實際的開發中一些典型的應用場景,
2.1.2.1、快取功能
下圖示比較典型的快取使用場景,其中Redis作為快取層,MySQL作為存盤層,絕大部分請求的資料都是從Redis中獲取,由于Redis具有支撐高并發的特性,所以快取通常能起到加速讀寫和降低后端壓力的作用,

2.1.2.2、計數
許多應用都會使用Redis作為計數的基礎工具,它可以實作快速計數、 查詢快取的功能,同時資料可以異步落地到其他資料源,例如記錄文章的閱讀次數,
2.1.2.3、共享Session
用于分布式應用的Session共享,保證用戶登錄一次即可訪問所有服務,

2.1.2.4、分布式鎖
利用setnx命令可以實作分布式鎖,由于Redis的單執行緒命令處理機制,如果有多個客戶端同時執行setnx key value, 根據setnx的特性只有一個客戶端能設定成功,所以setnx可以作為分布式鎖的一種實作方案,
以下是最簡單的Redis分布式鎖實作示意圖:

2.2、哈希
Redis 的字典和 Java 語言里面的 HashMap類似,在Redis中,哈希型別是指鍵值本身又是一個鍵值對結構,形如value={{field1,value1},…{fieldN,valueN}}

2.2.1、命令
- 設定值
hset key field value
下面為user:1添加一對field-value:
127.0.0.1:6379> hset user:1 name tom
(integer) 1
如果設定成功會回傳1,反之會回傳0,此外Redis提供了hsetnx命令,它們的關系就像set和setnx命令一樣,只不過作用域由鍵變為field,
- 獲取值
hget key field
獲取user:1的name域(屬性)對應的值:
127.0.0.1:6379> hget user:1 name
"tom"
- 洗掉field
hdel key field [field ...]
hdel會洗掉一個或多個field,回傳結果為成功洗掉field的個數,例如:
127.0.0.1:6379> hdel user:1 name
(integer) 1
127.0.0.1:6379> hdel user:1 age
(integer) 0
- 批量設定或獲取field-value
hmget key field [field ...]
hmset key field value [field value ...]
hmset和hmget分別是批量設定和獲取field-value,hmset需要的引數是key和多對field-value,hmget需要的引數是key和多個field,例如:
127.0.0.1:6379> hmset user:1 name mike age 12 city tianjin
OK
127.0.0.1:6379> hmget user:1 name city
1) "mike"
2) "tianjin"
2.2.2、應用場景
2.2.2.1、存盤物件
hash的filed-value的結構非常適合用來存盤物件,field用來存盤屬性名稱,value用來存盤屬性值,在一些客戶端里也提供了json序列化器,

2.3、串列
Redis 的串列類似于 Java 語言里面的 LinkedList,同樣地list 的插入和洗掉操作非常快,時間復雜度為 O(1),但是索引定位很慢,時間復雜度為O(n),
那么,同樣地,list也可以充當堆疊和佇列的角色,
例如,在list兩端的插入和彈出,可以模擬堆疊的操作:

串列型別有兩個特點:第一、串列中的元素是有序的,這就意味著可以通過索引下標獲取某個元素或者某個范圍內的元素串列,第二、串列中的元素可以是重復的,
2.3.1、命令
串列主要有5種操作型別:
| 操作型別 | 操作 |
|---|---|
| 添加 | rpush lpush linsert |
| 查找 | lrange lindex llen |
| 洗掉 | lpop rpop lren ltrim |
| 修改 | lset |
| 阻塞操作 | blpop brpop |
- 添加操作
從右邊插入元素
rpush key value [value ...]
下面代碼從右向左插入元素c、b、a:
127.0.0. 1:6379> rpush listkey c b a
(integer) 3
lrange0-1命令可以從左到右獲取串列的所有元素:
127.0.0.1:6379> lrange listkey 0 -1
1) "c"
2) "b"
3) "a"
從左邊插入元素類似,不再贅述
- 向某個元素前或者后插入元素
linsert key before|after pivot value
linsert命令會從串列中找到等于pivot的元素,在其前(before)或者后 (after)插入一個新的元素value,例如下面操作會在串列的元素b前插入 java:
127.0.0.1:6379> linsert listkey before b java
(integer) 4
回傳結果為4,代表當前命令的長度,當前串列變為:
127.0.0.1:6379> lrange listkey 0 -1
1) "c"
2) "java"
3) "b"
4) "a"
- 查找
獲取指定范圍內的元素串列
lrange key start end
lrange操作會獲取串列指定索引范圍所有的元素,
例如想獲取串列的第2到第4個元素:
127.0.0.1:6379> lrange listkey 1 3
1) "java"
2) "b"
3) "a"
獲取串列指定索引下標的元素
lindex key index
例如當前串列最后一個元素為a:
127.0.0.1:6379> lindex listkey -1
"a"
獲取串列長度
llen key
例如,下面示例當前串列長度為4:
127.0.0.1:6379> llen listkey
(integer) 4
- 洗掉
從串列左側彈出元素
lpop key
從串列右側彈出
rpop key
洗掉指定元素
lrem key count value
- 修改
lset key index newValue
- 阻塞操作
阻塞式彈出如下:
blpop key [key ...] timeout
brpop key [key ...] timeout
blpop和brpop是lpop和rpop的阻塞版本,它們除了彈出方向不同,使用方法基本相同,
2.3.2、應用場景
2.3.2.1、訊息佇列
Redis的lpush+brpop命令組合即可實作阻塞佇列,生產客戶端使用lrpush從串列左側插入元素,多個消費者客戶端使用brpop命令阻塞式的“搶”串列尾部的元素,多個客戶端保證了消費的負載均衡和高可用性,

list可以靈活組合,在不同的場景使用,總結如下:
-
lpush+lpop=Stack(堆疊)
-
lpush+rpop=Queue(佇列)
-
lpsh+ltrim=Capped Collection(有限集合)
-
lpush+brpop=Message Queue(訊息佇列)
2.4、集合
集合類似Java語言中的HashSet,集合中不允許有重復元素,并且集合中的元素是無序的,不能通過索引下標獲取元素,

2.4.1、命令
2.4.1.1、集合內操作
- 添加元素
sadd key element [element ...]
無法添加重復元素,添加重復元素會回傳0,
- 洗掉元素
srem key element [element ...]
- 計算元素個數
scard key
- 從集合隨機彈出元素
spop key
2.4.1.2、集合間操作
- 求多個集合的交集
sinter key [key ...]
- 求多個集合的并集
suinon key [key ...]
- 求多個集合的差集
sdiff key [key ...]

2.4.2、應用場景
2.4.2.1、標簽
集合型別比較典型的使用場景是標簽(tag),例如一個用戶可能對娛樂、體育比較感興趣,另一個用戶可能對歷史、新聞比較感興趣,這些興趣點就是標簽,有了這些資料就可以得到喜歡同一個標簽的人,以及用戶的共 同喜好的標簽,這些資料對于用戶體驗以及增強用戶黏度比較重要,
2.4.2.2、共同關注
可以利用交集的運算,實作社交社區用戶的“共同關注”功能,
2.5、有序集合
zset 可能是 Redis 提供的最為特色的資料結構,它類似于 Java 的 SortedSet 和 HashMap 的結合體,一方面它是一個 set,保證了內部value 的唯一性,另一方面它可以給每個 value 賦予一個 score,代表這個 value 的排序權重,

有序集合提供了獲取指定score和元素范圍查詢、計算成員排名等功能,合理的利用有序集合,能幫助
我們在實際開發中解決很多問題,
有序集合中的元素不能重復,但是score可以重復,就和一個班里的同學學號不能重復,但是考試成績可以相同,
2.5.1、命令
2.5.1.1、集合內
- 添加成員
zadd key score member [score member ...]
下面操作向有序集合user:rank添加用戶李四和他的score250:
127.0.0.1:6379> zadd user:ranking 250 李四
(integer) 1
- 計算成員個數
zcard key
- 計算某個成員的score
zscore key member
- 計算成員的排名
zrank key member zrevrank key member
- 洗掉成員
zrem key member [member ...]
2.5.1.2、集合間的操作
- 交集
zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
- 并集
zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
2.5.2、應用場景
有序集合比較適合用于需要排行的地方,
2.5.2.1、用戶點贊統計
可以用于統計博客、視頻網站等作品的點贊數,可以根據點贊數對作品進行排行,
3、基本資料型別內部編碼
通過上面的介紹,我們已經了解了五種基本資料結構,既然叫資料結構,那么一定是有內部的組成,就比如Java中的String由char或者byte陣列組成,我們這里簡單了解一下Redis五種基本資料結構的內部編碼,

3.1、字串
字串型別的內部編碼有3種:
-
int:8個位元組的長整型,
-
embstr:小于等于39個位元組的字串,
-
raw:大于39個位元組的字串,

3.2、哈希
哈希型別的內部編碼有兩種:
-
ziplist(壓縮串列):當哈希型別元素個數小于hash-max-ziplist-entries 配置(默認512個)、同時所有值都小于hash-max-ziplist-value配置(默認64 位元組)時,Redis會使用ziplist作為哈希的內部實作,ziplist使用更加緊湊的結構實作多個元素的連續存盤,所以在節省記憶體方面比hashtable更加優秀,
-
hashtable(哈希表):當哈希型別無法滿足ziplist的條件時,Redis會使用hashtable作為哈希的內部實作,因為此時ziplist的讀寫效率會下降,而hashtable的讀寫時間復雜度為O(1),
3.3、串列
串列型別的內部編碼有兩種,
-
ziplist(壓縮串列):當串列的元素個數小于list-max-ziplist-entries配置 (默認512個),同時串列中每個元素的值都小于list-max-ziplist-value配置時 (默認64位元組),Redis會選用ziplist來作為串列的內部實作來減少記憶體的使 用,
-
linkedlist(鏈表):當串列型別無法滿足ziplist的條件時,Redis會使用linkedlist作為串列的內部實作,
3.4、集合
集合型別的內部編碼有兩種:
-
intset(整數集合):當集合中的元素都是整數且元素個數小于set-max- intset-entries配置(默認512個)時,Redis會選用intset來作為集合的內部實作,從而減少記憶體的使用,
-
hashtable(哈希表):當集合型別無法滿足intset的條件時,Redis會使用hashtable作為集合的內部實作,
3.5、有序集合
有序集合型別的內部編碼有兩種:
-
ziplist(壓縮串列):當有序集合的元素個數小于zset-max-ziplist- entries配置(默認128個),同時每個元素的值都小于zset-max-ziplist-value配置(默認64位元組)時,Redis會用ziplist來作為有序集合的內部實作,ziplist 可以有效減少記憶體的使用,
-
skiplist(跳躍表):當ziplist條件不滿足時,有序集合會使用skiplist作為內部實作,因為此時ziplist的讀寫效率會下降,

這里只是簡單地了解一下,未來如果有機會,會再進一步學習Redis的實作來更深入地了解Redsi基本資料結構的內部原理,
參考:
【1】:《Redis開發與運維》
【2】:掘金小冊 《Redis 深度歷險:核心原理與應用實踐》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/279570.html
標籤:其他
上一篇:vue移動端自適應
