Redis基礎

目錄

1、Redis數據結構

2、strings

3、lists

4、sets

5、sorted sets

6、hashes

7、Rides持久化

8、主從同步

9 、Redis事務

10、Redis配置


1、Redis數據結構

redis是一種高級的key/value存儲系統,其中value支持五種數據類型:

strings、lists、sets、sorted sets、hashes

key不要太長,儘量不要超過1024字節,太長即消耗內存,也會降低查找效率,而且在一個項目中,key最好使用統一的命名模式

2、strings

如果只使用redis中的字符串類型,且不使用redis的持久化功能,那麼,redis就和memcache非常相似了


127.0.0.1:6379> set mynum "2"
OK
127.0.0.1:6379> get mynum
"2"
127.0.0.1:6379> incr mynum
(integer) 3
127.0.0.1:6379> get mynum
"3"

在遇到數值操作時,redis會將字符串類型轉換爲數值。而且由於incr等指令本身就具有原子操作的特性,所以我們完全可以利用redis的incr、incrby、decr、decrby等指令來實現原子計數的效果。

3、lists

redis中的lists在底層實現上並不是數組,而是鏈表。

lists中常用的命令有 lpush(左插)、rpush(右插)、lrange(提取)。

//新建一個list叫做mylist,並在列表頭部插入元素"1"
127.0.0.1:6379> lpush mylist "1" 
//返回當前mylist中的元素個數
(integer) 1 
//在mylist右側插入元素"2"
127.0.0.1:6379> rpush mylist "2" 
(integer) 2
//在mylist左側插入元素"0"
127.0.0.1:6379> lpush mylist "0" 
(integer) 3
//列出mylist中從編號0到編號1的元素
127.0.0.1:6379> lrange mylist 0 1 
1) "0"
2) "1"
//列出mylist中從編號0到倒數第一個元素
127.0.0.1:6379> lrange mylist 0 -1 
1) "0"
2) "1"
3) "2"

 

list常見應用:

1、可以利用lists來實現一個消息隊列,而且可以確保先後順序。

2、利用lrange實現分頁功能。

3、在博客系統中,每篇博文的評論也可以存入一個單獨的list中。

4、sets

redis的sets是一種無序的集合,集合中的元素沒有先後順序。

集合的相關操作也很豐富,如添加新元素、刪除元素、取交集、取並集、取差集

//向集合myset中加入一個新元素"one"
127.0.0.1:6379> sadd myset "one" 
(integer) 1
127.0.0.1:6379> sadd myset "two"
(integer) 1
//列出集合myset中的所有元素
127.0.0.1:6379> smembers myset 
1) "one"
2) "two"
//判斷元素1是否在集合myset中,返回1表示存在
127.0.0.1:6379> sismember myset "one" 
(integer) 1
//判斷元素3是否在集合myset中,返回0表示不存在
127.0.0.1:6379> sismember myset "three" 
(integer) 0
//新建一個新的集合yourset
127.0.0.1:6379> sadd yourset "1" 
(integer) 1
127.0.0.1:6379> sadd yourset "2"
(integer) 1
127.0.0.1:6379> smembers yourset
1) "1"
2) "2"
//對兩個集合求並集
127.0.0.1:6379> sunion myset yourset 
1) "1"
2) "one"
3) "2"
4) "two"

5、sorted sets

sorted sets中每個元素都關聯一個序號(score)

通常將redis中有序集合叫做zsets,這是因爲在redis中,有序集合的操作指令都是以z開頭的,如zadd、zrange、zrevrange、zrangebyscore


127.0.0.1:6379> zadd myzset 1 baidu.com 
(integer) 1
//向myzset中新增一個元素360.com,賦予它的序號是3
127.0.0.1:6379> zadd myzset 3 360.com 
(integer) 1
//向myzset中新增一個元素google.com,賦予它的序號是2
127.0.0.1:6379> zadd myzset 2 google.com 
(integer) 1
//列出myzset的所有元素,同時列出其序號,可以看出myzset已經是有序的了。
127.0.0.1:6379> zrange myzset 0 -1 with scores 
1) "baidu.com"
2) "1"
3) "google.com"
4) "2"
5) "360.com"
6) "3"
//只列出myzset的元素
127.0.0.1:6379> zrange myzset 0 -1 
1) "baidu.com"
2) "google.com"
3) "360.com"

 

6、hashes

hashes是在2.0版本以後才引入的。

//建立哈希,並賦值
127.0.0.1:6379> HMSET user:001 username antirez password P1pp0 age 34 
OK
//列出哈希的內容
127.0.0.1:6379> HGETALL user:001 
1) "username"
2) "antirez"
3) "password"
4) "P1pp0"
5) "age"
6) "34"
//更改哈希中的某一個值
127.0.0.1:6379> HSET user:001 password 12345 
(integer) 0
//再次列出哈希的內容
127.0.0.1:6379> HGETALL user:001 
1) "username"
2) "antirez"
3) "password"
4) "12345"
5) "age"
6) "34"

 

7、Rides持久化

redis提供了兩種持久化方式:

1、RDB(Rdies DataBase)

2、AOF(Append Only File)

RDB是將redis某一時刻的數據持久化到磁盤中,是一種快照式的持久化方法。redis在進行數據持久化的過程中,會將數據寫入到一個臨時文件中,等待持久化過程都結束了,纔會用這個臨時文件替換上次持久化好的文件。正式這種特性,讓我們可以隨時來進行備份,因爲快照文件總是完整可用的。redis會單獨fork一個子進程來進行持久化,而主進程是不會進行任何IO操作的,這樣就確保了redis極高的性能。如果需要進行大規模數據的恢復,且對於數據恢復的完整性不是很敏感,那麼RDB比AOF高效,如果對數據很敏感,RDB遇到故障時會有一段時間的數據丟失。

AOF是將執行過的寫指令記錄下來,在數據恢復的時候按照從前到後的順序再將指令執行一遍,默認的AOF持久化策略是每秒鐘fsync一次(fsync是指把緩存中的寫指令記錄到磁盤中),因爲在這種情況下,redis仍然可以保持很好的處理性能,即使redis故障,也只會丟失近1秒鐘的數據。如果在追加日誌時遇到故障導致日誌寫入不完整,可以使用redis-check-aof來進行日誌修復,因爲採用了追加的方式,如果不做任何處理的話,AOF文件會變的越來越大,因此,redis提供了AOF文件重寫機制,當AOF文件的大小超過所設定的閾值時,redis就會啓動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集。AOF在同樣數據規模下,AOF文件要比RDB文件更大,而且AOF的恢復速度也要慢於RDB。

如果AOF文件被寫壞,redis並不會貿然加載這個有問題的文件,而是報錯退出,可以通過以下步驟修復出錯的文件:

1、備份寫壞的AOF文件

2、運行redis-check-aof -fix進行修復

3、用diff -u來查看兩個文件的差異,確認問題

4、重啓redis,加載修復後的AOF文件

AOF重寫原理

在重寫開始之前,redis會fork一個“重寫子進程”,這個子進程首先會讀取現有的AOF文件,並將其包含的指令進行分析壓縮寫進一個臨時文件中。主進程會將新接收的寫指令一邊累積到內存緩衝區,一邊繼續寫入到原有的AOF文件中,從而保障原有的AOF文件是可用的,避免在重寫的過程中出現意外。當重寫子進程完成重寫工作後,它會給父進程一個信號,父進程收到信號後就會將內存中緩存的寫指令追加到新的AOF文件中,當追加結束後,redis就會用新的AOF文件來代替舊AOF文件,之後再有新的寫指令,就都會追加到新的AOF文件中

8、主從同步

redis支持主從同步,而且也支持一主多從以及多級從結構。主從結構,一是爲了純粹的冗餘備份,二是爲了提升讀性能,比如比較費時的操作交給從服務器承擔。redis主從同步是異步進行的,這意味着主從同步不會影響主邏輯,也不會降低redis的處理性能。在主從架構中,可以考慮關閉主服務器的數據持久化功能,只讓從服務器進行持久化,這樣可以提高主服務的處理性能。從服務器通常被設置爲只讀模式,這樣可以避免從服務器數據被誤修改。

主從同步原理

從服務器會向主服務器發出sync指令,當主服務器接收到此命令後,就會調用bgsave指令來創建一個子進程專門進行數據持久化工作,在數據持久化期間,主服務器將執行的寫指令都緩存在內存中,在bgsave指令執行完成後,主服務器會將持久化好的RDB文件發送給從服務器,這個動作完成後,主服務器會將這段時間緩存的寫指令再以redis協議的格式發送給從服務器。

即使多臺從服務器同時發來sync指令,主服務器也只會執行一次bgsave,然後把持久化好的RDB發送給從服務器,在2.8版本之前,主從一旦斷開連接,都會觸發一次主從之間全量的數據同步,而在2.8版本之後,redis支持了效率更高的增量同步(psync),大大降低了連接斷開的恢復成本。主服務器會在內存中維護一個緩衝區,緩衝區中存儲着將要發送給從服務器的內容,主從斷開連接後,從服務器會嘗試再次與主服務器連接,一旦連接成功,從服務器就會把“希望同步的主服務器id”和“希望請求的數據偏移”發送出去,主服務器收到校驗之後,就會將增量內容發送給從服務器。

9 、Redis事務

四個指令:multi、exec、discard、watch

redis> MULTI //標記事務開始
OK
redis> INCR user_id //多條命令按順序入隊
QUEUED
redis> INCR user_id
QUEUED
redis> INCR user_id
QUEUED
redis> PING
QUEUED
redis> EXEC //執行
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG

multi在組裝事務時,每一個命令都會進入到內存隊列中緩存起來,如果出現queued表示指令成功插入內存中緩存起來,在執行exec時,隊列中的命令將會被組裝成一個事務執行。

有關事務,通常會遇到兩種錯誤:

1、調用exec之前的錯誤

2、調用exec之後的錯誤

調用exec之前的錯誤有可能是語法錯誤導致的,也可能是內存不足導致的,只要出現某個命令無法成功寫入緩存隊列的情況,redis都會進行記錄,在客戶調用exec時,redis會拒絕執行這一事務。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> haha //一個明顯錯誤的指令
(error) ERR unknown command 'haha'
127.0.0.1:6379> ping
QUEUED
127.0.0.1:6379> exec
//redis無情的拒絕了事務的執行,原因是“之前出現了錯誤”
(error) EXECABORT Transaction discarded because of previous errors.

調用exec之後的錯誤,redis採用的策略是不處理這些錯誤,而是繼續向下執行事務中的其他命令。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 23
QUEUED
//age不是集合,所以如下是一條明顯錯誤的指令
127.0.0.1:6379> sadd age 15 
QUEUED
127.0.0.1:6379> set age 29
QUEUED
127.0.0.1:6379> exec //執行事務時,redis不會理睬第2條指令執行錯誤
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) OK
127.0.0.1:6379> get age
"29" //可以看出第3條指令被成功執行了

watch是一個很好用的命令,它可以幫助我們實現類似於“樂觀鎖”CAS的效果。

watch本身的作用是"監視key是否被改動過",而且支持同時監視多個key

127.0.0.1:6379> set age 23
OK
127.0.0.1:6379> watch age //開始監視age
OK
127.0.0.1:6379> set age 24 //在EXEC之前,age的值被修改了
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 25
QUEUED
127.0.0.1:6379> get age
QUEUED
127.0.0.1:6379> exec //觸發EXEC
(nil) //事務無法被執行

10、Redis配置

redis的配置文件被分成了如下幾個區域:

1.通用(general)
2.快照(snapshotting)
3.複製(replication)
4.安全(security)
5.限制(limits)
6.追加模式(append only mode)
7.LUA腳本(lua scripting)
8.慢日誌(slow log)
9.事件通知(event notification)

 

本文參考:https://blog.csdn.net/atco/article/details/51672577

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章