天天看點

分布式緩存學習筆記(一)四、通訊原理:

一、Redis介紹

一個開源的使用ANSI C語言編寫、遵守BSD協定、支援網絡、可基于記憶體亦可持久化的日志型、Key-Value資料庫,并提供多種語言的API。

它通常被稱為資料結構伺服器,因為值(value)可以是 字元串(String), 哈希(Map), 清單(list), 集合(sets) 和 有序集合(sorted sets)等類型。可以滿足很多應用場景。還提供了鍵過期,釋出訂閱,事務,流水線等附加功能

二、Redis使用場景

存儲緩存、投票、會話session、排行榜、計數器、釋出訂閱、消息隊列等

三、快速開始

下載下傳

$ wget http://download.redis.io/releases/redis-5.0.5.tar.gz

解壓

$ tar xzf redis-5.0.5.tar.gz

編譯

$ cd redis-5.0.5

$ make

檔案 說明
redis-server 啟動redis
redis-cli redis指令行用戶端
redis-benchmark 測試工具
redis-check-aof AOF持久化工具
redis-check-dump DB持久化工具
redis-sentinel 哨兵相關
redis-trib Redis cluster模式管理工具
redis.conf Redis的配置檔案
分布式緩存學習筆記(一)四、通訊原理:

缺點:單程序單線程(不足)指令慢 堵塞

優點:線程切換資源消耗

IO多路複用

1、redis安裝在磁盤

2、redis資料運作在記憶體

啟動

 ./src/redis-server redis.conf &

背景啟動

分布式緩存學習筆記(一)四、通訊原理:

檢視redis程序,啟動用戶端

啟動用戶端 src/redis-cli

分布式緩存學習筆記(一)四、通訊原理:

四、通訊原理:

分布式緩存學習筆記(一)四、通訊原理:

五、Redis日常操作

計數器:

CAS(Atomic原子操作)

incr age //必須為整數自加1,非整數傳回錯誤,無age鍵從0自增傳回1

decr age //整數age減1

incrby age 1 //整數age+1

decrby age 1//整數age -1

incrbyfloat score 3.3 //浮點型score+3.3

分布式緩存學習筆記(一)四、通訊原理:

字元串:

字元串類型:實際上可以是字元串(包括XML JSON),還有數字(整形 浮點數),二進制(圖檔 音頻 視訊),最大不能超過512MB

設值指令:

           set key value

           set name monkey ex 20  //20秒後過期  px 20000 毫秒過期

           setnx name monkey//不存在鍵name時,傳回1設定成功;存在的話失敗0

           set age 18 xx      //存在鍵age時,傳回1成功

批量設值:mset name monkey sex boy

批量擷取:mget name sex  (\r\n)

127.0.0.1:6379> set key yurz

OK

127.0.0.1:6379> get yurz

(nil)

127.0.0.1:6379> get key

"yurz"

127.0.0.1:6379> keys*

(error) ERR unknown command `keys*`, with args beginning with:

127.0.0.1:6379> keys *

1) "user:1"

2) "String"

3) "age"

4) "key"

5) "score"

127.0.0.1:6379> setnx name yurz ex 20

(error) ERR wrong number of arguments for 'setnx' command

127.0.0.1:6379> setnx name yurz

(integer) 1

127.0.0.1:6379> set age 18 xx

OK

127.0.0.1:6379> set age 18 xx

OK

127.0.0.1:6379> mset name yurz sex boy

OK

127.0.0.1:6379> mget name sec

1) "yurz"

2) (nil)

127.0.0.1:6379> mget name sex

1) "yurz"

2) "boy"

127.0.0.1:6379>
           

字元追加

append追加指令:

set name hello;

append name world //追加後成helloworld

字元串長度:

  set  monkey ’真帥’

strlen monkey//結果6,每個中文占3個位元組(utf-8)

截取字元串:  

 set name monkey;

getrange name 2 4//傳回“nke”


127.0.0.1:6379> mset name yurz sex boy

OK

127.0.0.1:6379> mget name sec

1) "yurz"

2) (nil)

127.0.0.1:6379> mget name sex

1) "yurz"

2) "boy"

127.0.0.1:6379> set name hello

OK

127.0.0.1:6379> append name world

(integer) 10

127.0.0.1:6379> get name

"helloworld"

127.0.0.1:6379> set yurz 'mm'

OK

127.0.0.1:6379> strlen yurz

(integer) 2

127.0.0.1:6379> set name yurz

OK

127.0.0.1:6379> getrange name 1 3

"urz"

127.0.0.1:6379>
           

Hash類型

哈希hash是一個string類型的field和value的映射表,hash特适合用于存儲對象

Id Username Sex age
1 Monkey Boy 18
2 Fox Boy

指令  hset key field value

   設值:hset user:1 name monkey         //成功傳回1,失敗傳回0

   取值:hget user:1 name              //傳回monkey

   删值:hdel user:1 age               //傳回删除的個數

   計算個數:hset user:1 name monkey; hset user:1 age 18;

             hlen user:1               //傳回2,user:1有兩個屬性值

   批量設值:hmset user:2 name monkey age 18sex boy //傳回OK

   批量取值:hmget user:2 name age sex   //傳回三行:monkey 18 boy

   判斷field是否存在:hexists user:2 name //若存在傳回1,不存在傳回0

   擷取所有field: hkeys user:2            // 傳回name age sex三個field

   擷取user:2所有value:hvals user:2     // 傳回monkey18 boy

   擷取user:2所有field與value:hgetall user:2 //name age sex monkey18 18 boy值

   增加1:hincrby user:2 age 1      //age+1

    hincrbyfloat user:2 age 2   //浮點型加2

127.0.0.1:6379> hset user:1 name monkey

(integer) 0

127.0.0.1:6379> hget user:1 name

"monkey"

127.0.0.1:6379> hdel user:1 name

(integer) 1

127.0.0.1:6379> hset user:1 name monkey; hset user:1 age 18;

(integer) 1

127.0.0.1:6379> hlen user:1

(integer) 3

127.0.0.1:6379> hmset user 2:name monkey age 18 sex boy;

OK

127.0.0.1:6379> hmget user:2 name age sex

1) (nil)

2) (nil)

3) (nil)

127.0.0.1:6379> hmget  name age sex

(error) WRONGTYPE Operation against a key holding the wrong kind of value

127.0.0.1:6379> hmset user:2 name monkey age 18 sex boy;

OK

127.0.0.1:6379> hmget user:2 name age sex

1) "monkey"

2) "18"

3) "boy;"

127.0.0.1:6379> hexists user:2 name age sex

(error) ERR wrong number of arguments for 'hexists' command

127.0.0.1:6379> hexists user:2 name

(integer) 1

127.0.0.1:6379> field:hkeys user:2

(error) ERR unknown command `field:hkeys`, with args beginning with: `user:2`,

127.0.0.1:6379> field:hkeys

(error) ERR unknown command `field:hkeys`, with args beginning with:

127.0.0.1:6379> field:hkeys user:2

(error) ERR unknown command `field:hkeys`, with args beginning with: `user:2`,

127.0.0.1:6379> hkeys user:2

1) "name"

2) "age"

3) "sex"

127.0.0.1:6379> hvals user:2

1) "monkey"

2) "18"

3) "boy;"

127.0.0.1:6379> hgetall user:2

1) "name"

2) "monkey"

3) "age"

4) "18"

5) "sex"

6) "boy;"

127.0.0.1:6379> hincrby user:2 age 1

(integer) 19

127.0.0.1:6379> hincrbyfloat user:2 age 2

"21"
           

List集合

用來存儲多個有序的字元串,一個清單最多可存2的32次方減1個元素

添加指令:

 rpush  monkey c b a //從右向左插入cba, 傳回值3

          lrange monkey 0 -1 //從左到右擷取清單所有元素 傳回 c b a

          lpush key c b a //從左向右插入cba

          linsert  monkey before b z//在b之前插入z, after為之後,使       用lrange monkey 0 -1 檢視:c z b a

查找指令:

 lrange key start end //索引下标特點:從左到右為0到N-1

          lindex monkey -1 //傳回最右末尾a,-2傳回b

          llen monkey  //傳回目前清單長度

          lpop monkey //把最左邊的第一個元素c删除

          rpop monkey //把最右邊的元素a删除

執行結果:

分布式緩存學習筆記(一)四、通訊原理:

 Set集合

使用者标簽,社交,查詢有共同興趣愛好的人,智能推薦

儲存多元素,與清單不一樣的是不允許有重複元素,且集合是無序,一個集合最多可存2的32次方減1個元素,除了支援增删改查,還支援集合交集、并集、差集;

 exists user    //檢查user鍵值是否存在

 sadd user a b c//向user插入3個元素,傳回3

 sadd user a b  //若再加入相同的元素,則重複無效,傳回0

 smembers user //擷取user的所有元素,傳回結果無序

 srem user a   //傳回1,删除a元素

 scard user    //傳回2,計算元素個數

分布式緩存學習筆記(一)四、通訊原理:

有序集合ZSET

常用于排行榜,如視訊網站需要對使用者上傳視訊做排行榜,或點贊數與集合有聯系,不能有重複的成員

指令:   

   zadd key score member [score member......]

例子:

   zadd user:zan 200 monkey //monkey的點贊數1, 傳回操作成功的條數1

   zadd user:zan 200 monkey 120 fox 100 lion// 傳回3

   zadd user:zan nx 100 monkey//鍵test:1必須不存在,主用于添加

   zadd user:zan xx incr 200 monkey//鍵test:1必須存在,主用于修改,此時為300

   zadd user:zan xx ch incr -299 monkey//傳回操作結果1,300-299=1

zrange user:zan 0  -1 withscores//檢視點贊(分數)與成員名

   zcard user:zan    //計算成員個數, 傳回1

排名場景:

   zadd user:3 200 monkey120 fox 100 lee//先插入資料

   zrange user:3 0 -1 withscores //檢視分數與成員

  zrank user:3 monkey//傳回名次:第3名傳回2,從0開始到2,共3名

  zrevrank user:3 monkey//傳回0, 反排序,點贊數越高,排名越前

分布式緩存學習筆記(一)四、通訊原理:
分布式緩存學習筆記(一)四、通訊原理:
分布式緩存學習筆記(一)四、通訊原理:

Redis全局指令:

1,檢視所有鍵:

keys *

2,鍵總數 :

dbsize       //2個鍵,如果存在大量鍵,線上禁止使用此指令

3,檢查鍵是否存在:

exists key  //存在傳回1,不存在傳回0

4,删除鍵:

del key      //del key, 傳回删除鍵個數,删除不存在鍵傳回0

5,鍵過期:

expire key seconds        //set name test  expire name 10,表示10秒過期

ttl key                            // 檢視剩餘的過期時間

6,鍵的資料結構類型:

type key //type hello     //傳回string,鍵不存在傳回none

分布式緩存學習筆記(一)四、通訊原理:
分布式緩存學習筆記(一)四、通訊原理:

六、Redis持久化

 作用:

 redis是一個支援持久化的記憶體資料庫,也就是說redis需要經常将記憶體中的資料同步到磁盤來保證持久化,持久化可以避免因程序退出而造成資料丢失;

RDB:

RDB持久化把目前程序資料生成快照(.rdb)檔案儲存到硬碟的過程,有手動觸發和自動觸發手動觸發有save和bgsave兩指令

   save指令:阻塞目前Redis,直到RDB持久化過程完成為止,若記憶體執行個體比較大會造成長時間阻塞,線上環境不建議用它

   bgsave指令:redis程序執行fork操作建立子線程,由子線程完成持久化,阻塞時間很短(微秒級),是save的優化,在執行redis-cli shutdown關閉redis服務時,如果沒有開啟AOF持久化,自動執行bgsave;

Save:

由于 save 指令是同步指令,會占用Redis的主程序。若Redis資料非常多時,save指令執行速度會非常慢,阻塞所有用戶端的請求。

是以很少在生産環境直接使用SAVE 指令,可以使用BGSAVE 指令代替。如果在BGSAVE指令的儲存資料的子程序發生錯誤的時,用 SAVE指令儲存最新的資料是最後的手段。

分布式緩存學習筆記(一)四、通訊原理:

Bgsave:

bgsave 指令執行一個異步操作,以RDB檔案的方式儲存所有資料的快照。

127.0.0.1:6379> bgsave Background saving started

分布式緩存學習筆記(一)四、通訊原理:

save 與 bgsave 對比

指令 save bgsave
IO類型 同步 異步
阻塞? 是(阻塞發生在fock(),通常非常快)
複雜度 O(n) O(n)
優點 不會消耗額外的記憶體 不阻塞用戶端指令
缺點 阻塞用戶端指令 需要fock子程序,消耗記憶體

操作:

指令:config set dir /usr/local  //設定rdb檔案儲存路徑

   備份:bgsave  //将dump.rdb儲存到usr/local下

   恢複:将dump.rdb放到redis安裝目錄與redis.conf同級目錄,重新開機redis即可

RDB優點:

一、壓縮後的二進制文,适用于備份、全量複制,用于災難恢複

     加載RDB恢複資料遠快于AOF方式

二、與AOF相比,在恢複大的資料集的時候,RDB方式會更快一些。

RDB缺點:

 一、無法做到實時持久化,每次都要建立子程序,頻繁操作成本過高

 二、儲存後的二進制檔案,存在老版本不相容新版本rdb檔案的問題

做,父程序不需要再做其他IO操作,是以RDB持久化方式可以最大化redis的性能。

分布式緩存學習筆記(一)四、通訊原理:
分布式緩存學習筆記(一)四、通訊原理:

AOF(存指令)

快照功能(RDB)并不是非常耐久(durable): 如果 Redis 因為某些原因而造成故障停機, 那麼伺服器将丢失最近寫入、且仍未儲存到快照中的那些資料。 從 1.1 版本開始, Redis 增加了一種完全耐久的持久化方式: AOF 持久化。

打開AOF後, 每當 Redis 執行一個改變資料集的指令時(比如 SET), 這個指令就會被追加到 AOF 檔案的末尾。這樣的話, 當 Redis 重新啟時, 程式就可以通過重新執行 AOF 檔案中的指令來達到重建資料集的目的。

分布式緩存學習筆記(一)四、通訊原理:

操作: 

開啟:redis.conf設定:appendonly yes  (預設不開啟,為no)

 預設檔案名:appendfilename "appendonly.aof"

分布式緩存學習筆記(一)四、通訊原理:

三種政策always、everysec、no對比

指令 優點 缺點 描述
always 不丢失資料 IO開銷大,一般SATA磁盤隻有幾百TPS 每次有新指令追加到 AOF 檔案時就執行一次 fsync :非常慢,也非常安全。
everysec 每秒進行與fsync,最多丢失1秒資料 可能丢失1秒資料

每秒 fsync 一次:足夠快(和使用 RDB 持久化差不多),并且在故障時隻會丢失 1 秒鐘的資料。

推薦(并且也是預設)的措施為每秒 fsync 一次, 這種 fsync 政策可以兼顧速度和安全性。

no 不用管 不可控 從不 fsync :将資料交給作業系統來處理,由作業系統來決定什麼時候同步資料。更快,也更不安全的選擇。
分布式緩存學習筆記(一)四、通訊原理:

AOF的優點

1、使用AOF 會讓你的Redis更加耐久: 你可以使用不同的fsync政策:無fsync,每秒fsync,每次寫的時候fsync。使用預設的每秒fsync政策,Redis的性能依然很好(fsync是由背景線程進行處理的,主線程會盡力處理用戶端請求),一旦出現故障,你最多丢失1秒的資料。

2、AOF檔案是一個隻進行追加的日志檔案,即使由于某些原因(磁盤空間已滿,寫的過程中當機等等)未執行完整的寫入指令,你也也可使用redis-check-aof工具修複這些問題。

3、Redis 可以在 AOF 檔案體積變得過大時,自動地在背景對 AOF 進行重寫: 重寫後的新 AOF 檔案包含了恢複目前資料集所需的最小指令集合。 整個重寫操作是絕對安全的,因為 Redis 在建立新 AOF 檔案的過程中,會繼續将指令追加到現有的 AOF 檔案裡面,即使重寫過程中發生停機,現有的 AOF 檔案也不會丢失。 而一旦新 AOF 檔案建立完畢,Redis 就會從舊 AOF 檔案切換到新 AOF 檔案,并開始對新 AOF 檔案進行追加操作。

3、AOF 檔案有序地儲存了對資料庫執行的所有寫入操作, 這些寫入操作以 Redis 協定的格式儲存, 是以 AOF 檔案的内容非常容易被人讀懂, 對檔案進行分析(parse)也很輕松。 導出(export) AOF 檔案也非常簡單: 舉個例子, 如果你不小心執行了 FLUSHALL 指令, 但隻要 AOF 檔案未被重寫, 那麼隻要停止伺服器, 移除 AOF 檔案末尾的 FLUSHALL 指令, 并重新開機 Redis , 就可以将資料集恢複到 FLUSHALL 執行之前的狀态。

AOF的缺點:

1、對于相同的資料集來說,AOF 檔案的體積通常要大于 RDB 檔案的體積。

2、根據所使用的 fsync 政策,AOF 的速度可能會慢于 RDB 。 在一般情況下, 每秒 fsync 的性能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency)

RDB 和 AOF 對比

- RDB AOF
啟動優先級
體積
恢複速度
資料安全性 丢資料 根據政策決定

繼續閱讀