Redis知識總結

最近在學校參與了一些項目,其中包含單點登錄(集羣),由於使用的redis,因此這裏簡單對redis作一個學習總結,reids的API的話就不放在本文浪費時間了,主要談談知識的自己node

在開始redis以前,咱們要了解,如今看成非關係型數據庫遠遠不止redis這一種,固然,之後可能也會更多,如果要依次學習全部的這類數據庫,那是很困難的,但他們都屬於nosql(not only sql非關係型數據庫),因此,咱們有必要先了解其根源,找到他們的通性,從其名字也能夠看出,他和關係型數據庫不是對立的,更多的是一種補充程序員

Nosql

爲何要有Nosql?

目前互聯網對技術提出了更多的要求,主要體如今如下方面:web

  • 低延遲的讀寫速度:應用快速地反應能極大地提高用戶的滿意度;
  • 海量的數據和流量:對於搜索這樣大型應用而言,須要利用PB級別的數據和能應對百萬級的流量;
  • 大規模集羣的管理:系統管理員但願分佈式應用能更簡單的部署和管理;
  • 龐大運營成本的考量:IT經理們但願在硬件成本、軟件成本和人力成本可以有大幅度地下降;

可是,關係型數據庫因爲自身的特色,讓他很難實現這些需求:redis

  • 擴展困難
  • 讀寫慢
  • 成本高
  • 支撐容量有限

因此,Nosql很是關注併發讀寫,大量數據存儲,它的優勢以下:算法

  • 高可擴展性
  • 分佈式計算
  • 低成本
  • 架構的靈活性,半結構化數據
  • 沒有複雜的關係

固然,Nosql也有缺點:sql

  • 不提供SQL語句支持
  • 特性不夠多(例如事務,在等會redis中會總結)

Nosql四大分類

鍵值(Key-Value)存儲數據庫

相關產品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB 典型應用: 內容緩存,主要用於處理大量數據的高訪問負載。 數據模型: 一系列鍵值對 優點: 快速查詢 劣勢: 存儲的數據缺乏結構化數據庫

列存儲數據庫

相關產品:Cassandra, HBase, Riak 典型應用:分佈式的文件系統 數據模型:以列簇式存儲,將同一列數據存在一塊兒 優點:查找速度快,可擴展性強,更容易進行分佈式擴展 劣勢:功能相對侷限緩存

文檔型數據庫

相關產品:CouchDB、MongoDB 典型應用:Web應用(與Key-Value相似,Value是結構化的) 數據模型: 一系列鍵值對 優點:數據結構要求不嚴格 劣勢: 查詢性能不高,並且缺少統一的查詢語法安全

圖形(Graph)數據庫

相關數據庫:Neo4J、InfoGrid、Infinite Graph 典型應用:社交網絡 數據模型:圖結構 優點:利用圖結構相關算法。 劣勢:須要對整個圖作計算才能得出結果,不容易作分佈式的集羣方案。bash

CAP定理

CAP定理意思是在分佈式計算系統中只能同時最多知足如下兩點

  • 一致性(Consistency) (全部節點在同一時間具備相同的數據)
  • 可用性(Availability) (保證每一個請求無論成功或者失敗都有響應)
  • 分隔容忍(Partition tolerance) (系統中任意信息的丟失或失敗不會影響系統的繼續運做) CAP理論的核心是:一個分佈式系統不可能同時很好的知足一致性,可用性和分區容錯性這三個需求,最多隻能同時較好的知足兩個。

所以,根據 CAP 原理將 NoSQL 數據庫分紅了知足 CA 原則、知足 CP 原則和知足 AP 原則三 大類:

  • CA - 單點集羣,知足一致性,可用性的系統,一般在可擴展性上不太強大。(傳統Oracle數據庫)
  • CP - 知足一致性,分區容忍性的系統,一般性能不是特別高。(Redis、Mongodb)
  • AP - 知足可用性,分區容忍性的系統,一般可能對一致性要求低一些。(大多數網站架構的選擇)
    image

注意:分佈式架構的時候必須作出取捨。一致性和可用性之間取一個平衡。多餘大多數web應用,其實並不須要強一致性。所以犧牲C換取P,這是目前分佈式數據庫產品的方向

Nosql總結

綜上所述,Nosql的出現更多的是爲了解決數據量大,分佈式中的問題,爲了數據吞吐量上的數量而對數據一致性打一點折扣。

e.g:

微博上一篇文章的點贊數,可能三秒內就會新增幾百個贊(行爲數據),這時,不可能保證用戶點一個贊就更新一次,這時,就可使用Nosql了。

而對於像轉帳這類(交易數據)的事務型操做,只能使用關係型數據庫了。

Redis

Redis是什麼

它是一個緩存數據庫,由C語言編寫,key-value存儲系統,屬於nosql

五大基本數據類型

1.字符串類型(String) 2.散列類型(hash) 3.列表類型(list) 4.集合類型(set) 5.有序集合類型(zset)

由於redis中都是存取的k-v鍵值對形式,這裏的基本數據類型指的是value的數據類型,全部的key都是字符串類型

關於它的API,這裏就不贅述了,看官方文檔便可

字符串類型

字符串是Redis最基本的數據類型,不只全部key都是字符串類型,其它幾種數據類型構成的元素也是字符串。注意字符串的長度不能超過512M。

這裏的字符串能夠是字符串,整數或者是浮點數,例如想知道一個ip訪問了多少次本網站,就能夠用INCRBY實現遞增。

列表類型

一個List結構能夠有序的存儲多個字符串,而且是容許元素重複的,能夠按照插入順序排序,能夠添加一個元素到列表的頭部(左邊)或者尾部(右邊),它的底層其實是個雙向鏈表結構。

Set集合類型

集合對象 set 是 string 類型(整數也會轉換成string類型進行存儲)的無序集合。經過散列表來保證本身存儲的每一個字符串都是各不相同的,即內部使用值爲空的散列表。

集合和列表的區別:集合中的元素是無序的,所以不能經過索引來操做元素;集合中的元素不能有重複。

Hash散列類型

哈希對象的鍵是一個字符串類型,值是一個鍵值對集合。

有序集合ZSET

有序集合對象是有序的。與列表使用索引下標做爲排序依據不一樣,有序集合爲每一個元素設置一個分數(score)做爲排序依據。

應用場景

  • 對於string 數據類型,由於string 類型是二進制安全的,能夠用來存放圖片,視頻等內容,另外因爲Redis的高性能讀寫功能,而string類型的value也能夠是數字,能夠用做計數器(INCR,DECR),好比分佈式環境中統計系統的在線人數,秒殺等。
  • 對於 hash 數據類型,value 存放的是鍵值對,好比能夠作單點登陸存放用戶信息。
  • 對於 list 數據類型,能夠實現簡單的消息隊列,另外能夠利用lrange命令,作基於redis的分頁功能
  • 對於 set 數據類型,因爲底層是字典實現的,查找元素特別快,另外set 數據類型不容許重複,利用這兩個特性咱們能夠進行全局去重,好比在用戶註冊模塊,判斷用戶名是否註冊;另外就是利用交集、並集、差集等操做,能夠計算共同喜愛,所有的喜愛,本身獨有的喜愛等功能。
  • 對於 zset 數據類型,有序的集合,能夠作範圍查找,排行榜應用,取 TOP N 操做等。

配置文件介紹

#redis.conf
# Redis configuration file example.
# ./redis-server /path/to/redis.conf

################################## INCLUDES ###################################
#這在你有標準配置模板可是每一個redis服務器又須要個性設置的時候頗有用。
# include /path/to/local.conf
# include /path/to/other.conf

################################ GENERAL #####################################

#是否在後臺執行,yes:後臺運行;no:不是後臺運行(老版本默認)
daemonize yes

  #3.2裏的參數,是否開啓保護模式,默認開啓。要是配置裏沒有指定bind和密碼。開啓該參數後,redis只會本地進行訪問,拒絕外部訪問。要是開啓了密碼 和bind,能夠開啓。否 則最好關閉,設置爲no。
  protected-mode yes
#redis的進程文件
pidfile /var/run/redis/redis-server.pid

#redis監聽的端口號。
port 6379

#此參數肯定了TCP鏈接中已完成隊列(完成三次握手以後)的長度, 固然此值必須不大於Linux系統定義的/proc/sys/net/core/somaxconn值,默認是511,而Linux的默認參數值是128。當系統併發量大而且客戶端速度緩慢的時候,能夠將這二個參數一塊兒參考設定。該內核參數默認值通常是128,對於負載很大的服務程序來講大大的不夠。通常會將它修改成2048或者更大。在/etc/sysctl.conf中添加:net.core.somaxconn = 2048,而後在終端中執行sysctl -p。
tcp-backlog 511

#指定 redis 只接收來自於該 IP 地址的請求,若是不進行設置,那麼將處理全部請求
bind 127.0.0.1

#配置unix socket來讓redis支持監聽本地鏈接。
# unixsocket /var/run/redis/redis.sock
#配置unix socket使用文件的權限
# unixsocketperm 700

# 此參數爲設置客戶端空閒超過timeout,服務端會斷開鏈接,爲0則服務端不會主動斷開鏈接,不能小於0。
timeout 0

#tcp keepalive參數。若是設置不爲0,就使用配置tcp的SO_KEEPALIVE值,使用keepalive有兩個好處:檢測掛掉的對端。下降中間設備出問題而致使網絡看似鏈接卻已經與對端端口的問題。在Linux內核中,設置了keepalive,redis會定時給對端發送ack。檢測到對端關閉須要兩倍的設置值。
tcp-keepalive 0

#指定了服務端日誌的級別。級別包括:debug(不少信息,方便開發、測試),verbose(許多有用的信息,可是沒有debug級別信息多),notice(適當的日誌級別,適合生產環境),warn(只有很是重要的信息)
loglevel notice

#指定了記錄日誌的文件。空字符串的話,日誌會打印到標準輸出設備。後臺運行的redis標準輸出是/dev/null。
logfile /var/log/redis/redis-server.log

#是否打開記錄syslog功能
# syslog-enabled no

#syslog的標識符。
# syslog-ident redis

#日誌的來源、設備
# syslog-facility local0

#數據庫的數量,默認使用的數據庫是DB 0。能夠經過」SELECT 「命令選擇一個db
databases 16

################################ SNAPSHOTTING ################################
# 快照配置
# 註釋掉「save」這一行配置項就可讓保存數據庫功能失效
# 設置sedis進行數據庫鏡像的頻率。
# 900秒(15分鐘)內至少1個key值改變(則進行數據庫保存--持久化) 
# 300秒(5分鐘)內至少10個key值改變(則進行數據庫保存--持久化) 
# 60秒(1分鐘)內至少10000個key值改變(則進行數據庫保存--持久化)
save 900 1
save 300 10
save 60 10000

#當RDB持久化出現錯誤後,是否依然進行繼續進行工做,yes:不能進行工做,no:能夠繼續進行工做,能夠經過info中的rdb_last_bgsave_status瞭解RDB持久化是否有錯誤
stop-writes-on-bgsave-error yes

#使用壓縮rdb文件,rdb文件壓縮使用LZF壓縮算法,yes:壓縮,可是須要一些cpu的消耗。no:不壓縮,須要更多的磁盤空間
rdbcompression yes

#是否校驗rdb文件。從rdb格式的第五個版本開始,在rdb文件的末尾會帶上CRC64的校驗和。這跟有利於文件的容錯性,可是在保存rdb文件的時候,會有大概10%的性能損耗,因此若是你追求高性能,能夠關閉該配置。
rdbchecksum yes

#rdb文件的名稱
dbfilename dump.rdb

#數據目錄,數據庫的寫入會在這個目錄。rdb、aof文件也會寫在這個目錄
dir /var/lib/redis

################################# REPLICATION #################################
#複製選項,slave複製對應的master。
# slaveof <masterip> <masterport>

#若是master設置了requirepass,那麼slave要連上master,須要有master的密碼才行。masterauth就是用來配置master的密碼,這樣能夠在連上master後進行認證。
# masterauth <master-password>

#當從庫同主機失去鏈接或者複製正在進行,從機庫有兩種運行方式:1) 若是slave-serve-stale-data設置爲yes(默認設置),從庫會繼續響應客戶端的請求。2) 若是slave-serve-stale-data設置爲no,除去INFO和SLAVOF命令以外的任何請求都會返回一個錯誤」SYNC with master in progress」。
slave-serve-stale-data yes

#做爲從服務器,默認狀況下是隻讀的(yes),能夠修改爲NO,用於寫(不建議)。
slave-read-only yes

#是否使用socket方式複製數據。目前redis複製提供兩種方式,disk和socket。若是新的slave連上來或者重連的slave沒法部分同步,就會執行全量同步,master會生成rdb文件。有2種方式:disk方式是master建立一個新的進程把rdb文件保存到磁盤,再把磁盤上的rdb文件傳遞給slave。socket是master建立一個新的進程,直接把rdb文件以socket的方式發給slave。disk方式的時候,當一個rdb保存的過程當中,多個slave都能共享這個rdb文件。socket的方式就的一個個slave順序複製。在磁盤速度緩慢,網速快的狀況下推薦用socket方式。
repl-diskless-sync no

#diskless複製的延遲時間,防止設置爲0。一旦複製開始,節點不會再接收新slave的複製請求直到下一個rdb傳輸。因此最好等待一段時間,等更多的slave連上來。
repl-diskless-sync-delay 5

#slave根據指定的時間間隔向服務器發送ping請求。時間間隔能夠經過 repl_ping_slave_period 來設置,默認10秒。
# repl-ping-slave-period 10

#複製鏈接超時時間。master和slave都有超時時間的設置。master檢測到slave上次發送的時間超過repl-timeout,即認爲slave離線,清除該slave信息。slave檢測到上次和master交互的時間超過repl-timeout,則認爲master離線。須要注意的是repl-timeout須要設置一個比repl-ping-slave-period更大的值,否則會常常檢測到超時。
# repl-timeout 60

#是否禁止複製tcp連接的tcp nodelay參數,可傳遞yes或者no。默認是no,即便用tcp nodelay。若是master設置了yes來禁止tcp nodelay設置,在把數據複製給slave的時候,會減小包的數量和更小的網絡帶寬。可是這也可能帶來數據的延遲。默認咱們推薦更小的延遲,可是在數據量傳輸很大的場景下,建議選擇yes。
repl-disable-tcp-nodelay no

#複製緩衝區大小,這是一個環形複製緩衝區,用來保存最新複製的命令。這樣在slave離線的時候,不須要徹底複製master的數據,若是能夠執行部分同步,只須要把緩衝區的部分數據複製給slave,就能恢復正常複製狀態。緩衝區的大小越大,slave離線的時間能夠更長,複製緩衝區只有在有slave鏈接的時候才分配內存。沒有slave的一段時間,內存會被釋放出來,默認1m。
# repl-backlog-size 5mb

#master沒有slave一段時間會釋放複製緩衝區的內存,repl-backlog-ttl用來設置該時間長度。單位爲秒。
# repl-backlog-ttl 3600

#當master不可用,Sentinel會根據slave的優先級選舉一個master。最低的優先級的slave,當選master。而配置成0,永遠不會被選舉。
slave-priority 100

#redis提供了可讓master中止寫入的方式,若是配置了min-slaves-to-write,健康的slave的個數小於N,mater就禁止寫入。master最少得有多少個健康的slave存活才能執行寫命令。這個配置雖然不能保證N個slave都必定能接收到master的寫操做,可是能避免沒有足夠健康的slave的時候,master不能寫入來避免數據丟失。設置爲0是關閉該功能。
# min-slaves-to-write 3

#延遲小於min-slaves-max-lag秒的slave才認爲是健康的slave。
# min-slaves-max-lag 10

# 設置1或另外一個設置爲0禁用這個特性。
# Setting one or the other to 0 disables the feature.
# By default min-slaves-to-write is set to 0 (feature disabled) and
# min-slaves-max-lag is set to 10.

################################## SECURITY ###################################
#requirepass配置可讓用戶使用AUTH命令來認證密碼,才能使用其餘命令。這讓redis可使用在不受信任的網絡中。爲了保持向後的兼容性,能夠註釋該命令,由於大部分用戶也不須要認證。使用requirepass的時候須要注意,由於redis太快了,每秒能夠認證15w次密碼,簡單的密碼很容易被攻破,因此最好使用一個更復雜的密碼。
# requirepass foobared

#把危險的命令給修改爲其餘名稱。好比CONFIG命令能夠重命名爲一個很難被猜到的命令,這樣用戶不能使用,而內部工具還能接着使用。
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

#設置成一個空的值,能夠禁止一個命令
# rename-command CONFIG ""
################################### LIMITS ####################################

# 設置能連上redis的最大客戶端鏈接數量。默認是10000個客戶端鏈接。因爲redis不區分鏈接是客戶端鏈接仍是內部打開文件或者和slave鏈接等,因此maxclients最小建議設置到32。若是超過了maxclients,redis會給新的鏈接發送’max number of clients reached’,並關閉鏈接。
# maxclients 10000

#redis配置的最大內存容量。當內存滿了,須要配合maxmemory-policy策略進行處理。注意slave的輸出緩衝區是不計算在maxmemory內的。因此爲了防止主機內存使用完,建議設置的maxmemory須要更小一些。
# maxmemory <bytes>

#內存容量超過maxmemory後的處理策略。
#volatile-lru:利用LRU算法移除設置過過時時間的key。
#volatile-random:隨機移除設置過過時時間的key。
#volatile-ttl:移除即將過時的key,根據最近過時時間來刪除(輔以TTL)
#allkeys-lru:利用LRU算法移除任何key。
#allkeys-random:隨機移除任何key。
#noeviction:不移除任何key,只是返回一個寫錯誤。
#上面的這些驅逐策略,若是redis沒有合適的key驅逐,對於寫命令,仍是會返回錯誤。redis將再也不接收寫請求,只接收get請求。寫命令包括:set setnx setex append incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby getset mset msetnx exec sort。
# maxmemory-policy noeviction

#lru檢測的樣本數。使用lru或者ttl淘汰算法,從須要淘汰的列表中隨機選擇sample個key,選出閒置時間最長的key移除。
# maxmemory-samples 5

############################## APPEND ONLY MODE ###############################
#默認redis使用的是rdb方式持久化,這種方式在許多應用中已經足夠用了。可是redis若是中途宕機,會致使可能有幾分鐘的數據丟失,根據save來策略進行持久化,Append Only File是另外一種持久化方式,能夠提供更好的持久化特性。Redis會把每次寫入的數據在接收後都寫入 appendonly.aof 文件,每次啓動時Redis都會先把這個文件的數據讀入內存裏,先忽略RDB文件。
appendonly no

#aof文件名
appendfilename "appendonly.aof"

#aof持久化策略的配置
#no表示不執行fsync,由操做系統保證數據同步到磁盤,速度最快。
#always表示每次寫入都執行fsync,以保證數據同步到磁盤。
#everysec表示每秒執行一次fsync,可能會致使丟失這1s數據。
appendfsync everysec

# 在aof重寫或者寫入rdb文件的時候,會執行大量IO,此時對於everysec和always的aof模式來講,執行fsync會形成阻塞過長時間,no-appendfsync-on-rewrite字段設置爲默認設置爲no。若是對延遲要求很高的應用,這個字段能夠設置爲yes,不然仍是設置爲no,這樣對持久化特性來講這是更安全的選擇。設置爲yes表示rewrite期間對新寫操做不fsync,暫時存在內存中,等rewrite完成後再寫入,默認爲no,建議yes。Linux的默認fsync策略是30秒。可能丟失30秒數據。
no-appendfsync-on-rewrite no

#aof自動重寫配置。當目前aof文件大小超過上一次重寫的aof文件大小的百分之多少進行重寫,即當aof文件增加到必定大小的時候Redis可以調用bgrewriteaof對日誌文件進行重寫。當前AOF文件大小是上第二天志重寫獲得AOF文件大小的二倍(設置爲100)時,自動啓動新的日誌重寫過程。
auto-aof-rewrite-percentage 100
#設置容許重寫的最小aof文件大小,避免了達到約定百分比但尺寸仍然很小的狀況還要重寫
auto-aof-rewrite-min-size 64mb

#aof文件可能在尾部是不完整的,當redis啓動的時候,aof文件的數據被載入內存。重啓可能發生在redis所在的主機操做系統宕機後,尤爲在ext4文件系統沒有加上data=ordered選項(redis宕機或者異常終止不會形成尾部不完整現象。)出現這種現象,能夠選擇讓redis退出,或者導入儘量多的數據。若是選擇的是yes,當截斷的aof文件被導入的時候,會自動發佈一個log給客戶端而後load。若是是no,用戶必須手動redis-check-aof修復AOF文件才能夠。
aof-load-truncated yes

################################ LUA SCRIPTING ###############################
# 若是達到最大時間限制(毫秒),redis會記個log,而後返回error。當一個腳本超過了最大時限。只有SCRIPT KILL和SHUTDOWN NOSAVE能夠用。第一個能夠殺沒有調write命令的東西。要是已經調用了write,只能用第二個命令殺。
lua-time-limit 5000

################################ REDIS CLUSTER ###############################
#集羣開關,默認是不開啓集羣模式。
# cluster-enabled yes

#集羣配置文件的名稱,每一個節點都有一個集羣相關的配置文件,持久化保存集羣的信息。這個文件並不須要手動配置,這個配置文件有Redis生成並更新,每一個Redis集羣節點須要一個單獨的配置文件,請確保與實例運行的系統中配置文件名稱不衝突
# cluster-config-file nodes-6379.conf

#節點互連超時的閥值。集羣節點超時毫秒數
# cluster-node-timeout 15000

#在進行故障轉移的時候,所有slave都會請求申請爲master,可是有些slave可能與master斷開鏈接一段時間了,致使數據過於陳舊,這樣的slave不該該被提高爲master。該參數就是用來判斷slave節點與master斷線的時間是否過長。判斷方法是:
#比較slave斷開鏈接的時間和(node-timeout * slave-validity-factor) + repl-ping-slave-period
#若是節點超時時間爲三十秒, 而且slave-validity-factor爲10,假設默認的repl-ping-slave-period是10秒,即若是超過310秒slave將不會嘗試進行故障轉移 
# cluster-slave-validity-factor 10

#master的slave數量大於該值,slave才能遷移到其餘孤立master上,如這個參數若被設爲2,那麼只有當一個主節點擁有2 個可工做的從節點時,它的一個從節點會嘗試遷移。
# cluster-migration-barrier 1

#默認狀況下,集羣所有的slot有節點負責,集羣狀態才爲ok,才能提供服務。設置爲no,能夠在slot沒有所有分配的時候提供服務。不建議打開該配置,這樣會形成分區的時候,小分區的master一直在接受寫請求,而形成很長時間數據不一致。
# cluster-require-full-coverage yes

################################## SLOW LOG ###################################
###slog log是用來記錄redis運行中執行比較慢的命令耗時。當命令的執行超過了指定時間,就記錄在slow log中,slog log保存在內存中,因此沒有IO操做。
#執行時間比slowlog-log-slower-than大的請求記錄到slowlog裏面,單位是微秒,因此1000000就是1秒。注意,負數時間會禁用慢查詢日誌,而0則會強制記錄全部命令。
slowlog-log-slower-than 10000

#慢查詢日誌長度。當一個新的命令被寫進日誌的時候,最老的那個記錄會被刪掉。這個長度沒有限制。只要有足夠的內存就行。你能夠經過 SLOWLOG RESET 來釋放內存。
slowlog-max-len 128

################################ LATENCY MONITOR ##############################
#延遲監控功能是用來監控redis中執行比較緩慢的一些操做,用LATENCY打印redis實例在跑命令時的耗時圖表。只記錄大於等於下邊設置的值的操做。0的話,就是關閉監視。默認延遲監控功能是關閉的,若是你須要打開,也能夠經過CONFIG SET命令動態設置。
latency-monitor-threshold 0

############################# EVENT NOTIFICATION ##############################
#鍵空間通知使得客戶端能夠經過訂閱頻道或模式,來接收那些以某種方式改動了 Redis 數據集的事件。由於開啓鍵空間通知功能須要消耗一些 CPU ,因此在默認配置下,該功能處於關閉狀態。
#notify-keyspace-events 的參數能夠是如下字符的任意組合,它指定了服務器該發送哪些類型的通知:
##K 鍵空間通知,全部通知以 __keyspace@__ 爲前綴
##E 鍵事件通知,全部通知以 __keyevent@__ 爲前綴
##g DEL 、 EXPIRE 、 RENAME 等類型無關的通用命令的通知
##$ 字符串命令的通知
##l 列表命令的通知
##s 集合命令的通知
##h 哈希命令的通知
##z 有序集合命令的通知
##x 過時事件:每當有過時鍵被刪除時發送
##e 驅逐(evict)事件:每當有鍵由於 maxmemory 政策而被刪除時發送
##A 參數 g$lshzxe 的別名
#輸入的參數中至少要有一個 K 或者 E,不然的話,無論其他的參數是什麼,都不會有任何 通知被分發。詳細使用能夠參考http://redis.io/topics/notifications

notify-keyspace-events ""

############################### ADVANCED CONFIG ###############################
#數據量小於等於hash-max-ziplist-entries的用ziplist,大於hash-max-ziplist-entries用hash
hash-max-ziplist-entries 512
#value大小小於等於hash-max-ziplist-value的用ziplist,大於hash-max-ziplist-value用hash。
hash-max-ziplist-value 64

#數據量小於等於list-max-ziplist-entries用ziplist,大於list-max-ziplist-entries用list。
list-max-ziplist-entries 512
#value大小小於等於list-max-ziplist-value的用ziplist,大於list-max-ziplist-value用list。
list-max-ziplist-value 64

#數據量小於等於set-max-intset-entries用iniset,大於set-max-intset-entries用set。
set-max-intset-entries 512

#數據量小於等於zset-max-ziplist-entries用ziplist,大於zset-max-ziplist-entries用zset。
zset-max-ziplist-entries 128
#value大小小於等於zset-max-ziplist-value用ziplist,大於zset-max-ziplist-value用zset。
zset-max-ziplist-value 64

#value大小小於等於hll-sparse-max-bytes使用稀疏數據結構(sparse),大於hll-sparse-max-bytes使用稠密的數據結構(dense)。一個比16000大的value是幾乎沒用的,建議的value大概爲3000。若是對CPU要求不高,對空間要求較高的,建議設置到10000左右。
hll-sparse-max-bytes 3000

#Redis將在每100毫秒時使用1毫秒的CPU時間來對redis的hash表進行從新hash,能夠下降內存的使用。當你的使用場景中,有很是嚴格的實時性須要,不可以接受Redis時不時的對請求有2毫秒的延遲的話,把這項配置爲no。若是沒有這麼嚴格的實時性要求,能夠設置爲yes,以便可以儘量快的釋放內存。
activerehashing yes

##對客戶端輸出緩衝進行限制能夠強迫那些不從服務器讀取數據的客戶端斷開鏈接,用來強制關閉傳輸緩慢的客戶端。
#對於normal client,第一個0表示取消hard limit,第二個0和第三個0表示取消soft limit,normal client默認取消限制,由於若是沒有尋問,他們是不會接收數據的。
client-output-buffer-limit normal 0 0 0
#對於slave client和MONITER client,若是client-output-buffer一旦超過256mb,又或者超過64mb持續60秒,那麼服務器就會當即斷開客戶端鏈接。
client-output-buffer-limit slave 256mb 64mb 60
#對於pubsub client,若是client-output-buffer一旦超過32mb,又或者超過8mb持續60秒,那麼服務器就會當即斷開客戶端鏈接。
client-output-buffer-limit pubsub 32mb 8mb 60

#redis執行任務的頻率爲1s除以hz。
hz 10

#在aof重寫的時候,若是打開了aof-rewrite-incremental-fsync開關,系統會每32MB執行一次fsync。這對於把文件寫入磁盤是有幫助的,能夠避免過大的延遲峯值。
aof-rewrite-incremental-fsync yes
複製代碼

持久化

前文說過,redis是內存數據庫,爲了保證數據在斷電後不會丟失,須要將它持久化到硬盤上。redis持久化分爲兩種。

RDB持久化

RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤。

也是默認的持久化方式,這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲dump.rdb。

能夠經過配置設置自動作快照持久化的方式。咱們能夠配置redis在n秒內若是超過m個key被修改就自動作快照,下面是默認的快照保存配置

  • save 900 1 #900秒內若是超過1個key被修改,則發起快照保存
  • save 300 10 #300秒內容如超過10個key被修改,則發起快照保存
  • save 60 10000
RDB保存過程
  • redis調用fork,如今有了子進程和父進程
  • 父進程繼續處理client請求,子進程負責將內存內容寫入到臨時文件。因爲os的寫時複製機制(copy on write)父子進程會共享相同的物理頁面,當父進程處理寫請求時os會爲父進程要修改的頁面建立副本,而不是寫共享的頁面。因此子進程的地址空間內的數 據是fork時刻整個數據庫的一個快照。
  • 當子進程將快照寫入臨時文件完畢後,用臨時文件替換原來的快照文件,而後子進程退出。
如何觸發快照

client 也可使用save或者bgsave命令通知redis作一次快照持久化。save操做是在主線程中保存快照的,因爲redis是用一個主線程來處理全部 client的請求,這種方式會阻塞全部client請求。因此不推薦使用。

另外一點須要注意的是,每次快照持久化都是將內存數據完整寫入到磁盤一次,並不 是增量的只同步髒數據。若是數據量大的話,並且寫操做比較多,必然會引發大量的磁盤io操做,可能會嚴重影響性能。

優點
  • 一旦採用該方式,那麼你的整個Redis數據庫將只包含一個文件,這樣很是方便進行備份
  • 方便備份,咱們能夠很容易的將一個一個RDB文件移動到其餘的存儲介質上
  • RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
  • RDB 能夠最大化 Redis 的性能:父進程在保存 RDB 文件時惟一要作的就是 fork 出一個子進程,而後這個子進程就會處理接下來的全部保存工做,父進程無須執行任何磁盤 I/O 操做。
劣勢
  • 若是你須要儘可能避免在服務器故障時丟失數據,那麼 RDB 不適合你。 雖然 Redis 容許你設置不一樣的保存點(save point)來控制保存 RDB 文件的頻率, 可是, 由於RDB 文件須要保存整個數據集的狀態, 因此它並非一個輕鬆的操做。 所以你可能會至少 5 分鐘才保存一次 RDB 文件。 在這種狀況下, 一旦發生故障停機, 你就可能會丟失好幾分鐘的數據。(丟失數據)
  • 每次保存 RDB 的時候,Redis 都要 fork() 出一個子進程,並由子進程來進行實際的持久化工做。 在數據集比較龐大時, fork() 可能會很是耗時,形成服務器在某某毫秒內中止處理客戶端; 若是數據集很是巨大,而且 CPU 時間很是緊張的話,那麼這種中止時間甚至可能會長達整整一秒。 雖然 AOF 重寫也須要進行 fork() ,但不管 AOF 重寫的執行間隔有多長,數據的耐久性都不會有任何損失。(耗時)
rdb總結

image

AOF持久化

AOF保存過程

redis會將每個收到的寫命令都經過write函數追加到文件中(默認是 appendonly.aof)。

當redis重啓時會經過從新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。固然因爲os會在內核中緩存 write作的修改,因此可能不是當即寫到磁盤上。這樣aof方式的持久化也仍是有可能會丟失部分修改。不過咱們能夠經過配置文件告訴redis咱們想要 經過fsync函數強制os寫入到磁盤的時機。有三種方式以下(默認是:每秒fsync一次)

appendonly yes //啓用aof持久化方式

appendfsync always //每次收到寫命令就當即強制寫入磁盤,最慢的,可是保證徹底的持久化,不推薦使用

appendfsync everysec //每秒鐘強制寫入磁盤一次,在性能和持久化方面作了很好的折中,推薦

appendfsync no //徹底依賴os,性能最好,持久化沒保證

aof 的方式也同時帶來了另外一個問題。持久化文件會變的愈來愈大。例如咱們調用incr test命令100次,文件中必須保存所有的100條命令,其實有99條都是多餘的。由於要恢復數據庫的狀態其實文件中保存一條set test 100就夠了。

爲了壓縮aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis將使用與快照相似的方式將內存中的數據以命令的方式保存到臨時文件中,最後替換原來的文件。具體過程以下

redis調用fork,如今有父子兩個進程子進程根據內存中的數據庫快照,往臨時文件中寫入重建數據庫狀態的命令父進程繼續處理client請求,除了把寫命令寫入到原來的aof文件中。同時把收到的寫命令緩存起來。這樣就能保證若是子進程重寫失敗的話並不會出問題。當子進程把快照內容寫入已命令方式寫到臨時文件中後,子進程發信號通知父進程。而後父進程把緩存的寫命令也寫入到臨時文件。如今父進程可使用臨時文件替換老的aof文件,並重命名,後面收到的寫命令也開始往新的aof文件中追加。 須要注意到是重寫aof文件的操做,並無讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點相似

優點
  • 耐久
  • 不斷電
  • 易讀
劣勢
  • 數據量大

抉擇

通常來講,應該同時使用兩種持久化功能。 若是你很是關心你的數據, 但仍然能夠承受數分鐘之內的數據丟失, 那麼你能夠只使用 RDB 持久化。

redis事務

是什麼

能夠一次執行多個命令,本質是一組命令的集合。一個事務中的,全部命令都會序列化,按順序地串行化執行而不會被其它命令插入,不準加塞

能幹嗎

一個隊列中,一次性、順序性、排他性的執行一系列命令

3個階段

  • 開啓:以MULTI開始一個事務
  • 入隊:將多個命令入隊到事務中,接到這些命令並不會當即執行,而是放到等待執行的事務隊列裏面
  • 執行:由EXEC命令觸發事務

3特性

  • 單獨的隔離操做:事務中的全部命令都會序列化、按順序地執行。事務在執行的過程當中,不會被其餘客戶端發送來的命令請求所打斷。
  • 沒有隔離級別的概念:隊列中的命令沒有提交以前都不會實際的被執行,由於事務提交前任何指令都不會被實際執行,
  • 也就不存在」事務內的查詢要看到事務裏的更新,在事務外查詢不能看到」這個讓人萬分頭痛的問題
  • 不保證原子性:redis同一個事務中若是有一條命令執行失敗,其後的命令仍然會被執行,沒有回滾

關於redis事務

首先,讓咱們來看一個例子:

image
這個操做採用了事務模式,並在第6個指令 進入隊列的時候就已經出錯,因此致使整個事務的命令都不會被執行

接下來,再看一個操做

image

實際上這個問題很簡單,這個incr name錯誤指令在入隊的時候沒有出錯,卻在執行的時候出錯了,redis默認跳過這個命令執行後續命令

因此,這就是爲何我在開頭說redis的事務只是部分事務

redis的鎖機制

redis的鎖CAS相似於樂觀鎖,使用方式爲用watch關鍵字監視一個(或多個)數據,例如:

假設如今兩個客戶端A,B

1.客戶端A監控count,並修改count

image

2.待A執行完畢後,客戶端B修改count

image

3.待B執行完畢後,A提交事務

image

能夠看到,顯示了(nil),即此次事務失敗,count變爲50

事務總結

  • 單獨的隔離操做:事務中的全部命令會被序列化、按順序執行,在執行的過程當中不會被其餘客戶端發送來的命令打斷
  • 沒有隔離級別的概念:隊列中的命令在事務沒有被提交以前不會被實際執行
  • 不保證原子性:redis中的一個事務中若是存在命令執行失敗,那麼其餘命令依然會被執行,沒有回滾機制

消息發佈訂閱

Redis提供了發佈訂閱功能,可用於消息傳輸,進程間的一種通訊方式,Redis的發佈訂閱機制包括三個部分,發佈者,訂閱者和Channel。

發佈者和訂閱者都是Redis客戶端,Channel則爲Redis服務器端,發佈者將消息發送到某個的頻道,訂閱了這個頻道的訂閱者就能接收到這條消息。

固然,通常不多人用redis的發佈訂閱,取而代之的是消息隊列MQ(ActiveMQ),但仍是有必要了解redis有該功能的。

主從複製

爲何有它

  • 讀寫分離:和關係型數據庫同樣,雖然redis做爲內存數據庫,他一樣面臨讀寫壓力,經過設置主從redis能夠實現讀寫分離減輕壓力
  • 容災恢復:假設某位程序員不當心把庫房燒了😭,主庫沒了,若是咱們設計了從庫,這時咱們將徹底不用擔憂數據沒了的問題,由於從庫和主庫有一樣的數據

是什麼

行話:也就是咱們所說的主從複製,主機數據更新後根據配置和策略,自動同步到備機的master/slaver機制,Master以寫爲主,Slave以讀爲主,一個從服務器只能有一個主服務器,而且不支持主主複製。

複製原理

全量同步

Redis全量複製通常發生在Slave初始化階段,這時Slave須要將Master上的全部數據都複製一份。具體步驟以下:

1.從服務器鏈接主服務器,發送SYNC命令;

2.主服務器接收到SYNC命名後,開始執行BGSAVE命令生成RDB文件並使用緩衝區記錄此後執行的全部寫命令;

3.主服務器BGSAVE執行完後,向全部從服務器發送快照文件,並在發送期間繼續記錄被執行的寫命令;

4.從服務器收到快照文件後丟棄全部舊數據,載入收到的快照;

5.主服務器快照發送完畢後開始向從服務器發送緩衝區中的寫命令;

6.從服務器完成對快照的載入,開始接收命令請求,並執行來自主服務器緩衝區的寫命令;

增量同步

Redis增量複製是指Slave初始化後開始正常工做時主服務器發生的寫操做同步到從服務器的過程。 增量複製的過程主要是主服務器每執行一個寫命令就會向從服務器發送相同的寫命令,從服務器接收並執行收到的寫命令。

如今,出現了幾個問題:

  • 從機是否能夠寫?
  • 若是從庫死了以後活了他仍是從庫嗎?
  • 若是主庫死了以後它的從庫該怎麼辦?(普通模式和哨兵模式)主庫活了以後仍是主庫嗎?
爲了減小閱讀量,這裏就不實驗論證了,客官們能夠自行嘗試
先回答第一個問題:

從機不可寫

先回答第二個問題:

在Redis2.8版本以前,從庫死後復活會發送sync請求和主機全量同步,因此死後復活仍是從庫,可是,當多個從庫同時復活的話會致使主機IO劇增而宕機

2.8版本以後,主服務器只須要將斷線期間執行的命令發給從服務器便可

第三個問題:

主機死後,從機待命。而且主庫回來後,他將仍然是主庫

哨兵模式:反客爲主,即哨兵模式在後臺監控,主庫死後根據投票將它的從庫設置爲新的主庫

哨兵模式的出現正是爲了解決主庫死後無人領導的狀態。

那麼有了哨兵模式後,原來死掉的主庫回來後會發生什麼呢?答案是原來的主庫回來後就變爲了從庫。

最後一點點

對於一個slave從庫他一樣能夠接收其餘從庫的鏈接請求,即該slave做爲下一個的master

Redis適用場景

  • 數據高併發讀寫
  • 海量數據讀寫
  • 擴展性要求高的數據

例子:

1.保存熱點信息 2.排行榜 3.計數 4.單點登錄(解決session共享問題) 5.等等。。。

相關文章
相關標籤/搜索