讀書筆記之《Redis開發與運維》—— 一

前言

    讀書筆記系列主要記錄本身看的書籍中的知識點,算是一個概括整理吧。Redis在咱們的平常開發中能夠說是很經常使用了,《Redis開發與運維》
這本書講解了Redis開發和運維的方方面面,很系統、全面,關鍵是實用。特來擼擼它,記錄一番。全書分爲14章,下面將記錄我的認爲每章中重要的知識點。redis

1、Redis初識

    Redis是一種基於鍵值對(key-value)的NoSQL數據庫,Redis中的值能夠是由string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位圖)、HyperLogLog、GEO(地理信息定位)等多種數據結構和算法構成,能夠知足不少的應用場景。由於Redis會將全部數據都放在內存裏,因此它的讀寫性能很是好。Redis還能夠將內存的數據利用快照和日誌的形式保存到硬盤上,這樣發生斷電或者機器故障,內存中的數據就不會丟失。固然Redis還提供了其餘不少附加功能。算法

一、Redis特性

(1)速度快數據庫

Redis的全部數據都是放在內存裏的,這是速度快的最主要緣由;
Redis是用C語言實現的,「距離」操做系統更近,執行速度相對會更快;
Redis採用單線程架構,預防了多線程可能產生的競爭問題;編程

(2)基於鍵值對的數據結構緩存

Redis中的值不只能夠是字符串,還能夠是具體的數據結構,方面在不一樣應用場景的開發。Redis主要提供五種數據結構:字符串、哈希、列表、集合、有序列表,而且在字符串的基礎上演變出來了位圖(Bitmaps)和HyperLogLog倆種「數據結構」。Redis3.2版本加入了GEO(地理信息定位)的功能。網絡

(3)豐富的功能session

除了5種數據結構,還有其餘額外的許多功能:數據結構

鍵過時功能,用來實現緩存;
發佈訂閱功能,用來實現消息系統;
Lua腳本功能,利用Lua腳本創造出新的Redis命令;
簡單的事務功能,在必定程度上保證事務特性;
流水線(Pipeline)功能,客戶端能將一批命令一次性傳到Redis,減小網絡開銷。多線程

(4)簡單穩定架構

代碼少,單線程,服務端、客戶端處理簡單,redis不依賴操做系統中的類庫,本身實現了事件處理的相關功能。

(5)客戶端語言多

redis提供了簡單的TCP通訊協議,不少編程語言能夠很方便的接入到redis。

(6)持久化

redis提供了兩種持久化方式:RDB和AOF。能夠用這兩種策略將內存的數據保存在硬盤中,保證了數據的可持久性。

(7)主從複製

redis提供了複製功能,實現了多個相同數據的redis副本,複製功能是分佈式redis的基礎。

(8)高可用和分佈式

redis提供了高可用實現Redis Sentinel(哨兵),可以保證redis節點的故障發現和故障自動轉移。而且3.0版本提供了分佈式實現Redis Cluster(集羣),
這是redis真正的分佈式實現,提供了高可用、讀寫和容量的擴展性。

二、Redis使用場景

緩存、排行榜系統、計數器應用(redis自然支持計數功能,且計數性能很好)、社交網絡(粉絲、共同喜愛、推送等,社交網站的訪問量比較大,傳統的關係型數據庫不太適合保存這種類型的數據,可用redis實現)、消息隊列系統(消息隊列具備業務解耦、非實時業務削峯等特性,redis能夠知足通常的消息隊列功能,不過通常項目中仍是使用專業的消息隊列,更增強大)。

redis也有不適合它解決的問題場景,站在數據規模和數據冷熱角度來分析的話:數據規模角度,數據可分爲大規模數據和小規模數據,redis的數據是放在內存裏的,若是數據規模很是大,不適合使用redis存儲;站在數據冷熱角度,數據分爲熱數據和冷數據,熱數據是指須要頻繁操做的數據,若是將冷數據放在redis中,浪費內存。

2、API的理解和使用

一、全局命令

(1)查看全部鍵:keys *

(2)鍵總數:dbsize

注意:dbsize命令在計算總數時候不會遍歷全部鍵,而是直接獲取redis內部的鍵總數變量,時間複雜度O(1);而keys命令會遍歷全部鍵,時間複雜度O(n),若是redis保存了大量鍵時,線上環境禁止使用。

(3)檢查鍵是否存在(鍵存在返回1,不存在返回0):exists key

(4)刪除鍵(返回的結果是成功刪除的個數,刪除一個不存在的鍵,返回0):del key [key ...]

注意:del key表示刪除一個,del key1 key2 key3表示刪除3個

(5)鍵過時:expire key seconds

注意:redis支持對鍵添加過時時間,超過過時時間後,會自動刪除鍵;ttl key 命令會返回鍵的剩餘過時時間,返回值>=0表示鍵的剩餘過時時間,返回值-1表示鍵沒有設置過時時間,返回值-2表示鍵不存在。

(6)鍵的數據結構類型:type key

注意:若是鍵是字符串類型,返回string,若是鍵是列表類型,返回list,其餘幾種相似。若是鍵不存在,返回none。

二、數據結構的內部編碼

每種數據結構都有本身底層的內部編碼實現,並且是多種實現,redis會在合適的場景選擇合適的內部編碼。好比zset包含skiplist和ziplist兩種內部編碼。這樣設計的好處是:能夠改進內部編碼,而對外的數據結構和命令沒有影響;多種內部編碼實現能夠在不一樣場景下發揮各自的優點,好比ziplist比較節省內存,可是在列表元素比較多的狀況下,性能會有所降低,這個時候redis會根據配置選項將列表類型的內部實現轉換爲linkedlist。

三、單線程架構

redis使用單線程架構和I/O多路複用模型來實現高性能的內存數據庫服務。一條命令從客戶端達到服務端不會馬上執行,全部命令都會進入到一個隊列中,而後逐個被執行。不會有兩條命令被同時執行。redis使用了I/O多路複用技術來解決I/O的問題。

redis使用單線程模式那麼快的緣由:純內存訪問,這個最重要;非阻塞I/O,redis使用epoll做爲I/O多路複用技術的實現,而且redis加上自身的事件處理模型將epoll中的鏈接、讀寫、關閉都轉換爲事件,不在網絡I/O上浪費過多的時間;單線程避免了線程切換和競爭產生的消耗。

注意:單線程會有一個問題,對於每一個命令的執行時間是有要求的,若是執行時間過長,會形成其餘命令的阻塞,對於redis來講是致命的,因此redis是面向快速執行場景的數據庫。

四、字符串

(1)設置值:set key value [ex seconds] [px milliseconds] [nx|xx]

注意:nx 鍵必須不存在,才能夠設置成功,用於添加; xx 鍵必須存在,才能夠設置成功,用於更新

(2)獲取值:get key

批量設置值:mset key value [key value ...]

批量獲取值:mget key [key ...]

注意:批量操做能夠減小網絡時間(n次網絡時間+n次命令時間 ---> 1次網絡時間+n次命令時間),可是每次批量操做所發送的命令不是無節制的,若是數量過多可能形成redis阻塞或者網絡阻塞。

(3)計數:incr key

incr命令用於對值作自增操做,若是值不是整數,返回錯誤;若是值是整數,返回自增後的結果;若是鍵不存在,按照值爲0自增,返回結果1。

不少存儲系統和編程語言內部使用CAS機制實現計數功能,會有必定的CPU開銷,但redis中不存在這個問題,由於redis單線程架構,任何命令到了redis服務端都要順序執行。

(4)內部編碼(redis會根據當前值的類型和長度決定使用哪一種內部編碼實現)

int(8個字節的長整形) embstr(小於等於39個字節的字符串) raw(大於39個字節的字符串)

(5)典型應用場景

緩存功能、計數、共享session、限速

五、哈希

(1)設置值

hset key field value

(2)獲取值

hget key field

(3)批量設置或獲取field-value

hmget key field [field ...]
hmset key field value [field value ...]

(4)內部編碼(ziplist、hashtable)

當哈希類型的field個數小於512,而且全部的value小於64字節,使用ziplist做爲哈希的內部實現,不然使用hashtable。512和64是默認的,能夠配置。

(5)應用場景

好比:用戶信息

六、列表

列表是用來存儲多個有序的字符串,能夠對列表兩端插入和彈出。列表類型有兩個特色:(1)列表中的元素是有序的;(2)列表中的元素能夠是重複的。

(1)從右端插入、從左端插入

rpush key value [value ...] lpush key value [value ...]

lrange 0 -1 表示從左到右獲取列表的全部元素

(2)內部編碼(ziplist、linkedlist、quicklist)

當列表的元素個數小於512個,而且列表的每一個元素值都小於64字節,redis會選用ziplist來做爲列表的內部實現,不然選用linkedlist。Redis3.2版本提供了quicklist內部編碼,它是以一個ziplist爲節點的linkedlist,結合了ziplist和linkedlist二者的優點。

(3)使用場景

例如:消息隊列、文章列表

七、集合

集合中不容許有重複元素,而且集合中的元素是無序的。

(1)添加元素

sadd key elements [elements ...]

(2)刪除元素

srem key elements [elements ...]

(3)內部編碼(intset、hashtable)

當集合中的元素都是整數且元素個數小於512(默認值,可配置),redis選用intset做爲集合內部實現,不然選用hashtable。

(4)使用場景

標籤、社交等,好比一個用戶對可樂、體育感興趣,另外一個用戶對歷史、新聞感興趣,這些興趣點就是標籤。

八、有序集合

不能有重複成員,元素能夠排序,每一個元素設置一個分數(score)做爲排序的依據。有序集合的元素不能重複,可是分數能夠重複。

(1)添加成員

zadd key score member [score member ...]

(2)內部編碼(ziplist、skiplist)

當有序集合的元素個數小於128個,而且每一個元素的值都小於64字節,Redis使用ziplist做爲有序集合的內部實現。不然使用skiplist。

(3)使用場景

排行榜系統

九、健管理

(1)單個健管理

返回鍵類型、鍵重命名、鍵過時、遷移鍵等。

注意:遷移鍵有三種方式:move、dump+restore、migrate。move命令用於redis內部進行數據遷移,從一個數據庫遷移到另外一個數據庫,不建議生產環境使用redis多數據庫功能;dump+restore能夠實如今不一樣redis實例之間進行數據遷移,分爲dump和restore兩步,其中在源redis上dump會將鍵值序列化,採用RDB格式,在目標redis上,restore會將上面序列化的值復原;migrate命令用於redis實例之間進行數據遷移,實際上migrate是將dump、restore、del三個命令進行了整合。migrate命令的數據傳輸直接在源redis和目標redis上完成。

move命令做用於redis實例內部,是原子性的,不支持多個鍵;dump+restore做用於redis實例之間,不是原子性,不支持多個鍵;migrate做用於redis實例之間,是原子性的,支持多個鍵。

(2)遍歷鍵(keys和scan)

keys會全量遍歷全部鍵,可能形成redis阻塞。scan能夠想象成只掃描字典中的一部分鍵,直到將字典中的全部鍵遍歷完畢。scan能夠有效解決
keys命令可能產生的阻塞問題,可是scan的過程當中,若是有鍵的變化(增長、刪除、修改),就可能新鍵沒有遍歷到或者遍歷了重複的健。因此scan不能保證完整的遍歷出來全部的健。

(3)數據庫管理

select dbIndex 切換數據庫

flushdb/flushall 清除數據庫,flushdb只清除當前數據庫,flushall清除全部數據庫。

相關文章
相關標籤/搜索