目錄
- 1.入門概述
- 1.1redis是什么?
- 1.2redis能干什么?
- 1.3redis官網?
- 1.4從哪些方面去學習redis?
- 2.Redis的安裝及啟動關閉
- 2.1Linux(CentOS 6.9)下安裝redis(3.0.4)
- 2.2查看默認安裝目錄:usr/local/bin
- 2.3啟動
- 2.4關閉
- 3.Redis啟動后雜項基礎知識
- 3.1單行程
- 3.2redis資料庫的一些概念及操作
- 4.redis 鍵(key) --(常用命令介紹)
- 5.redis的五大資料型別
- 5.1string(字串)
- 5.2list(串列)
- 5.3hash(哈希,類似java里的Map)
- 5.4set(集合)
- 5.5zset(sorted set:有序集合)
- 5.6redis常見資料型別操作命令參考網址
- 6.決議組態檔(redis.conf)
- 6.1INCLUDES(包含)
- 6.2GENERAL(通用)
- 6.3SNAPSHOTTING(快照)
- 6.4REPLICATION(復制)
- 6.5SECURITY(安全)
- 6.6LIMITS(極限)
- 6.7APPEND ONLY MODE(追加)
- 6.8常見的一些配置總結
- 7.Redis的持久化
- 7.1RDB(Redis DataBase)
- 7.1.1RDB介紹
- 7.1.2如何觸發RDB快照
- 7.1.3如何恢復
- 7.1.4如何停止
- 7.1.5優勢
- 7.1.6劣勢
- 7.2AOF(Append Only File)
- 7.2.1AOF介紹
- 7.2.2rewrite
- 7.2.3優勢
- 7.2.4劣勢
- 7.3總結(Which One)
- 7.1RDB(Redis DataBase)
- 8.Redis的事務
- 8.1redis事務簡介
- 8.2redis事務能干什么
- 8.3redis事務執行五種情況
- 8.4悲觀鎖/樂觀鎖/CAS(Check And Set)
- 8.4.1悲觀鎖
- 8.4.2樂觀鎖
- 8.5redis事務執行的程序
- 8.6redis事務的特性
- 9.Redis的復制(Master | Slave)
- 9.1Redis復制簡介
- 9.2Redis的復制能干什么
- 9.3Redis復制如何去應用
- 9.4Redis復制的原理
- 9.5哨兵模式(sentinel)
- 9.6復制的缺點
1.入門概述
1.1redis是什么?
Redis:REmote DIctionary Server(遠程字典服務器)
是完全開源免費的,用C語言撰寫的,遵守BSD協議,是一個高性能的(key/value)分布式記憶體資料庫,基于記憶體運行并支持持久化的NoSQL資料庫,是當前最熱門的NoSql資料庫之一,也被人們稱為資料結構服務器,
Redis 與其他 key - value 快取產品有以下三個特點:
- Redis支持資料的持久化,可以將記憶體中的資料保持在磁盤中,重啟的時候可以再次加載進行使用;
- Redis不僅僅支持簡單的key-value型別的資料,同時還提供list,set,zset,hash等資料結構的存盤;
- Redis支持資料的備份,即master-slave模式的資料備份;
1.2redis能干什么?
- 記憶體存盤和持久化:redis支持異步將記憶體中的資料寫到硬碟上,同時不影響繼續服務;
- 取最新N個資料的操作,如:可以將最新的10條評論的ID放在Redis的List集合里面;
- 模擬類似于HttpSession這種需要設定過期時間的功能;
- 發布、訂閱訊息系統;
- 定時器、計數器;
1.3redis官網?
- http://redis.io/
- http://www.redis.cn/
1.4從哪些方面去學習redis?
- 資料型別、基本操作和配置;
- 持久化和復制,RDB/AOF;
- 事務的控制;
- 復制;
2.Redis的安裝及啟動關閉
由于企業里面做Redis開發,99%都是Linux版的運用和安裝,幾乎不會涉及到Windows版,所以Windows版不作為講解;
2.1Linux(CentOS 6.9)下安裝redis(3.0.4)
- 下載獲得redis-3.0.4.tar.gz后將它放入我們的Linux目錄/opt;
- /opt目錄下,解壓命令:tar -zxvf redis-3.0.4.tar.gz;
- 解壓完成后出現檔案夾:redis-3.0.4;
- 進入目錄:cd redis-3.0.4;
- 在redis-3.0.4目錄下執行make命令;
運行make命令時出現的錯誤:
- 安裝gcc(能上網:yum install gcc-c++);
- 再次make;
如果make完成后繼續執行make install;
2.2查看默認安裝目錄:usr/local/bin
redis-benchmark:服務啟動起來后執行性能測驗工具,可以在自己本子運行,看看自己本子性能如何;
redis-check-aof:修復有問題的aof檔案;
redis-check-dump:修復有問題的dump.rdb檔案;
redis-cli:客戶端,操作入口;
redis-sentinel:redis集群使用;
redis-server:Redis服務器啟動命令;
2.3啟動
- 修改redis.conf檔案將里面的daemonize no 改成 yes,讓服務在后臺啟動;
- 將默認的redis.conf拷貝到自己定義好的一個路徑下,比如/myconf/redis.conf;
- 進入/usr/local/bin目錄下運行redis-server,運行拷貝出存放了自定義myconf檔案目錄下的
- redis.conf檔案(redis-server /myconf/redis.conf);
- 在/usr/local/bin目錄下運行redis-cli,啟動客戶端(redis-cli -p 6379);
2.4關閉
- 單實體關閉:redis-cli shutdown;
- 多實體關閉,指定埠關閉:redis-cli -p 6379 shutdown;
3.Redis啟動后雜項基礎知識
3.1單行程
- 單行程模型來處理客戶端的請求,對讀寫等事件的回應是通過對epoll函式的包裝來做到的,Redis的實際處理速度完全依靠主行程的執行效率;
- epoll是Linux內核為處理大批量檔案描述符而作了改進的epoll,是Linux下多路復用IO介面select/poll的增強版本,它能顯著提高程式在大量并發連接中只有少量活躍的情況下的系統CPU利用率;
3.2redis資料庫的一些概念及操作
- 默認16個資料庫,類似陣列下表從零開始,初始默認使用零號庫;
- 統一密碼管理,16個庫都是同樣密碼,要么都OK要么一個也連接不上,redis默認埠是6379;
- select命令切換資料庫:select 0-15;
- dbsize:查看當前資料庫的key的數量;
- flushdb:清空當前庫;
- flushall;通殺全部庫;
4.redis 鍵(key) --(常用命令介紹)
KEYS *:查看所有key;
DEL key:洗掉當前的key
DUMP key:序列化給定key,回傳被序列化的值
EXISTS key:檢查key是否存在
EXPIRE key second:為key設定過期時間
TTL key:查看還有多少秒過期,-1表示永不過期,-2表示已過期;
PERSIST key:移除key的過期時間,key將持久保存
KEY pattern:查詢所有符號給定模式的key
RANDOM key:隨機回傳一個key
RANAME key newkey:修改key的名稱
MOVE key db(id0-15):移動key至指定資料庫中
TYPE key:回傳key所儲存的值的型別
5.redis的五大資料型別
5.1string(字串)
string是redis最基本的型別,你可以理解成與Memcached一模一樣的型別,一個key對應一個value;
string型別是二進制安全的,意思是redis的string可以包含任何資料,如jpg圖片或者序列化的物件 ;
string型別是Redis最基本的資料型別,一個redis中字串value最多可以是512M;
set/get/del/append/strlen;
Incr/decr/incrby/decrby:一定要是數字才能進行加減;
getrange/setrange:
getrange:獲取指定區間范圍內的值,類似between and的關系從零到負一表示全部;
setrange:設定指定區間范圍內的值,格式是setrange key 位置值 具體值;
setex(set with expire) 鍵 秒值 值/setnx(set if not exist) 鍵
setex:設定帶過期時間的key,動態設定 : setex 鍵 秒值 真實值
setnx:只有在 key 不存在時設定 key 的值:setnx 鍵 值
mset/mget/msetnx
mset:同時設定一個或多個 key-value 對,
mget:獲取所有(一個或多個)給定 key 的值,
msetnx:同時設定一個或多個 key-value 對,當且僅當所有給定 key 都不存在(如果存在key,則都不會操作,因為msetnx是原子性型操作),
getset:將給定 key 的值設為 value ,并回傳 key 的舊值(old value),簡單一句話,先get然后立即set,
String應用場景:
- String通常用于保存單個字串或JSON字串資料
- 因為String是二進制安全的,所以可以把保密要求高的圖片檔案內容作為字串來存盤
- 計數器:常規Key-Value快取應用,如微博數、粉絲數,INCR本身就具有原子性特性,所以不會有執行緒安全問題
5.2list(串列)
redis 串列是簡單的字串串列,按照插入順序排序,你可以添加一個元素導串列的頭部(左邊)或者尾部(右邊),它的底層實際是個鏈表,
lpush key value1 [value2]
rpush key value1 [value2]
lpushx key value:從左側插入值,如果list不存在,則不操作
rpushx key value:從右側插入值,如果list不存在,則不操作
llen key:獲取串列長度
lindex key index:獲取指定索引的元素
lrange key start stop:獲取串列指定范圍的元素
lpop key :從左側移除第一個元素
prop key:移除串列最后一個元素
blpop key [key1] timeout:移除并獲取串列第一個元素,如果串列沒有元素會阻塞串列到等待超時或發現可彈出元素為止
brpop key [key1] timeout:移除并獲取串列最后一個元素,如果串列沒有元素會阻塞串列到等待超時或發現可彈出元素為止
ltrim key start stop :對串列進行修改,讓串列只保留指定區間的元素,不在指定區間的元素就會被洗掉
lset key index value :指定索引的值
linsert key before|after world value:在串列元素前或則后插入元素
應用場景
- 對資料大的集合資料刪減
串列顯示、關注串列、粉絲串列、留言評價...分頁、熱點新聞等 - 任務佇列
list通常用來實作一個訊息佇列,而且可以確保先后順序,不必像MySQL那樣通過order by來排序
性能總結
它是一個字串鏈表,left、right都可以插入添加;
- 如果鍵不存在,創建新的鏈表;
- 如果鍵已存在,新增內容;
- 如果值全移除,對應的鍵也就消失了,
- 鏈表的操作無論是頭和尾效率都極高,但假如是對中間元素進行操作,效率就很慘淡了,
5.3hash(哈希,類似java里的Map)
redis的hash 是一個鍵值對集合;
redis hash是一個string型別的field和value的映射表,hash特別適合用于存盤物件;
hset/hget/hmset/hmget/hgetall/hdel,格式:
hset key field value:將哈希表 key 中的域 field 的值設為 value ;
hget key field:回傳哈希表 key 中給定域 field 的值;
hmset key field value [field value ...]:同時將多個 field-value (域-值)對設定到哈希表 key 中;
hmget key field [field ...]:回傳哈希表 key 中,一個或多個給定域的值;
hgetall key:回傳哈希表 key 中,所有的域和值;
hdel key field [field ...]:洗掉哈希表 key 中的一個或多個指定域,不存在的域將被忽略;
hlen,回傳哈希表 key 中域的數量(格式:hlen key);
hexists,查看哈希表 key 中,給定域 field 是否存在(格式:hexists key field);
hkeys/hvals,格式:
hkeys key:回傳哈希表 key 中的所有域;
hvals key:回傳哈希表 key 中所有域的值;
hincrby/hincrbyfloat,格式:
hincrby key field increment:為哈希表 key 中的域 field 的值加上增量 increment;
hincrbyfloat key field increment:為哈希表 key 中的域 field 加上浮點數增量 increment ;
hsetnx,將哈希表 key 中的域 field 的值設定為 value ,當且僅當域 field 不存在(格式:hsetnx key field value)
應用場景s
Hash的應用場景,通常用來存盤一個用戶資訊的物件資料,
- 相比于存盤物件的string型別的json串,json串修改單個屬性需要將整個值取出來,而hash不需要,
- 相比于多個key-value存盤物件,hash節省了很多記憶體空間
- 如果hash的屬性值被洗掉完,那么hash的key也會被redis洗掉
5.4set(集合)
redis的set是string型別的無序集合,它是通過HashTable實作的,
sadd/smembers/sismember,格式:
sadd key member [member ...]
smembers key
sismember key member
scard:獲取集合里面的元素個數(格式:scard key);
srem:洗掉集合中元素(格式:srem key member [member ...]);
srandmember,(格式:srandmember key [count])(不會修改set集合)
如果命令執行時,只提供了 key 引數,那么回傳集合中的一個隨機元素;
如果 count 為正數,且小于集合基數,那么命令回傳一個包含 count 個元素的陣列,陣列中的元素各不相同,如果 count 大于等于集合基數,那么回傳整個集合;
如果 count 為負數,那么命令回傳一個陣列,陣列中的元素可能會重復出現多次,而陣列的長度為 count 的絕對值;
spop,移除并回傳集合中的一個隨機元素(格式:spop key);
smove,(格式:smove source destination member)將 member 元素從 source 集合移動到 destination 集合;
差集:sdiff(格式:sdiff key [key ...])
交集:sinter(格式:sinter key [key ...])
并集:sunion(格式:sunion key [key ...])
應用場景
對兩個集合間的資料[計算]進行交集、并集、差集運算
- 以非常方便的實作如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的命令選擇將結果回傳給客戶端還是存盤到一個新的集合中,
- 利用唯一性,可以統計訪問網站的所有獨立 IP
5.5zset(sorted set:有序集合)
redis的zset 和 set 一樣也是string型別元素的集合,且不允許重復的成員;
不同的是每個元素都會關聯一個double型別的分數;
redis正是通過分數來為集合中的成員進行從小到大的排序,zset的成員是唯一的,但分數(score)卻可以重復;
zadd/zrange,格式:
zadd key score member [[score member] [score member] ...]:將一個或多個 member 元素及其 score 值加入到有序集 key 當中;
zrange key start stop [WITHSCORES]:回傳有序集 key 中,指定區間內的成員,其中成員的位置按 score 值遞增(從小到大)來排列;
zrangebyscore:(格式:zrangebuscore key min max [WITHSCORES] [LIMIT offset count]),回傳有序集 key 中,所有 score 值介于 min 和 max 之間(包括等于 min 或 max )的成員;
zrem:移除有序集 key 中的一個或多個成員,不存在的成員將被忽略(格式:zrem key member [member ...]);
zcard/zcount /zrank/zscore,格式:
zcard key:回傳有序集 key 的基數;
zcount key min max:回傳有序集 key 中, score 值在 min 和 max 之間(默認包括 score 值等于 min 或 max )的成員的數量;
zrank key member:回傳有序集 key 中成員 member 的排名,其中有序集成員按 score 值遞增(從小到大)順序排列,排名以 0 為底,也就是說, score 值最小的成員排名為 0 ;
zscore key member:回傳有序集 key 中,成員 member 的 score 值;
zrevrank:回傳有序集 key 中成員 member 的排名,其中有序集成員按 score 值遞減(從大到小)排序,排名以 0 為底,也就是說, score 值最大的成員排名為 0 (格式:zrevrank key member);
zrevrange:回傳有序集 key 中,指定區間內的成員,其中成員的位置按 score 值遞減(從大到小)來排列(格式:zrevrange key start stop [WITHSCORES]);
zrevrangebyscore:回傳有序集 key 中, score 值介于 max 和 min 之間(默認包括等于 max 或 min )的所有的成員,有序集成員按 score 值遞減(從大到小)的次序排列(格式:zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]);
應用場景
- 如推特可以以發表時間作為score來存盤
- 存盤成績
- 還可以用zset來做帶權重的佇列,讓重要的任務先執行
5.6redis常見資料型別操作命令參考網址
http://redisdoc.com/
6.決議組態檔(redis.conf)
6.1INCLUDES(包含)
可以通過includes包含,redis.conf可以作為總閘,包含其他;
6.2GENERAL(通用)
daemonize no
Redis默認不是以守護行程的方式運行,可以通過該配置項修改,使用yes啟用守護行程;
啟用守護行程后,Redis會把pid寫到一個pidfile中,在/var/run/redis.pid;
pidfile /var/run/redis.pid
當Redis以守護行程方式運行時,Redis默認會把pid寫入/var/run/redis.pid檔案,可以通過pidfile指定;
port 6379
指定Redis監聽埠,默認埠為6379;
如果指定0埠,表示Redis不監聽TCP連接;
tcp-backlog 511
設定tcp的backlog,backlog其實是一個連接佇列,backlog佇列總和=未完成三次握手佇列 + 已經完成三次握手佇列,在高并發環境下你需要一個高backlog值來避免慢客戶端連接問題(注意Linux內核會將這個值減小到/proc/sys/net/core/somaxconn的值),所以需要增大somaxconn和tcp_max_syn_backlog兩個值來達到想要的效果;
bind 127.0.0.1
系結的主機地址;
你可以系結單一介面,如果沒有系結,所有介面都會監聽到來的連接;
timeout 0
當客戶端閑置多長時間后關閉連接,如果指定為0,表示關閉該功能;
tcp-keepalive 0
TCP連接保活策略;
單位為秒,如果設定為0,則不會進行Keepalive檢測,建議設定成60 ;
loglevel notice
指定日志記錄級別,Redis總共支持四個級別:debug、verbose、notice、warning;
logfile ""
指定了記錄日志的檔案,空字串的話,日志會列印到標準輸出設備,后臺運行的redis標準輸出是/dev/null;
syslog-enabled no
是否把日志輸出到syslog中;
syslog-ident redis
指定syslog里的日志標志
syslog-facility local0
指定syslog設備,值可以是USER或LOCAL0-LOCAL7;
databases 16
設定資料庫的數量,默認資料庫為0;
6.3SNAPSHOTTING(快照)
save
指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合;
save 900 1:900秒(15分鐘)內有1個更改
save 300 10:300秒(5分鐘)內有10個更改
save 60 10000:60秒(1分鐘)內有10000個更改
stop-writes-on-bgsave-error yes
后臺存盤錯誤停止寫;
rdbcompression yes
指定存盤至本地資料庫時是否壓縮資料,默認為yes,Redis采用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導致資料庫檔案變的巨大;
rdbchecksum yes
在存盤快照后,還可以讓redis使用CRC64演算法來進行資料校驗,但是這樣做會增加大約10%的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能;
dbfilename dump.rdb
指定本地資料庫檔案名,默認值為dump.rdb;
dir ./
指定本地資料庫存放目錄(rdb、aof檔案也會寫在這個目錄);
6.4REPLICATION(復制)
詳細請看下文Redis的復制(Master | Slave);
6.5SECURITY(安全)
requirepass foobared
設定Redis連接密碼,如果配置了連接密碼,客戶端在連接Redis時需要通過auth password命令提供密碼,默認關閉;
6.6LIMITS(極限)
maxclients 10000
設定redis同時可以與多少個客戶端進行連接,默認情況下為10000個客戶端,當你無法設定行程檔案句柄限制時,redis會設定為當前的檔案句柄限制值減去32,因為redis會為自身內部處理邏輯留一些句柄出來,如果達到了此限制,redis則會拒絕新的連接請求,并且向這些連接請求方發出“max number of clients reached”以作回應;
maxmemory <bytes>
設定redis可以使用的記憶體量,一旦到達記憶體使用上限,redis將會試圖移除內部資料,移除規則可以通過maxmemory-policy來指定,如果redis無法根據移除規則來移除記憶體中的資料,或者設定了“不允許移除”,那么redis則會針對那些需要申請記憶體的指令回傳錯誤資訊,比如SET、LPUSH等,但是對于無記憶體申請的指令,仍然會正常回應,比如GET等,如果你的redis是主redis(說明你的redis有從redis),那么在設定記憶體使用上限時,需要在系統中留出一些記憶體空間給同步佇列快取,只有在你設定的是“不移除”的情況下,才不用考慮這個因素
maxmemory-policy noeviction
資料淘汰策略,Reids 具體有 6 種淘汰策略:
(1)volatile-lru:使用LRU演算法移除key,只對設定了過期時間的鍵;
(2)allkeys-lru:使用LRU演算法移除key;
(3)volatile-random:在過期集合中移除隨機的key,只對設定了過期時間的鍵;
(4)allkeys-random:移除隨機的key;
(5)volatile-ttl:移除那些TTL值最小的key,即那些最近要過期的key;
(6)noeviction:不進行移除,針對寫操作,只是回傳錯誤資訊;
maxmemory-samples 5
設定樣本數量,LRU演算法和最小TTL演算法都并非是精確的演算法,而是估算值,所以你可以設定樣本的大小,redis默認會檢查這么多個key并選擇其中LRU的那個;
6.7APPEND ONLY MODE(追加)
appendonly no
指定是否在每次更新操作后進行日志記錄,Redis在默認情況下是異步的把資料寫入磁盤,如果不開啟,可能會在斷電時導致一段時間內的資料丟失;因為redis本身同步資料檔案是按上面save條件來同步的,所以有的資料會在一段時間內只存在于記憶體中,默認為no;
appendfilename "appendonly.aof"
指定更新日志檔案名,默認為appendonly.aof;
appendfsync everysec
always:同步持久化,每次發生資料變更會被立即記錄到磁盤 性能較差但資料完整性比較好;
everysec:出廠默認推薦,異步操作,每秒記錄 如果一秒內宕機,有資料丟失;
no:讓作業系統來決定何時同步,不能給服務器性能帶來多大的提升,而且也會增加系統奔潰時資料丟失的數量;
no-appendfsync-on-rewrite no
重寫時是否可以運用Appendfsync,用默認no即可,保證資料安全性;
auto-aof-rewrite-percentage 100
重寫指定百分比,為0會禁用AOF自動重寫特性;
auto-aof-rewrite-min-size 64mb
設定重寫的基準值;
6.8常見的一些配置總結
redis.conf 配置項說明如下:
1.Redis默認不是以守護行程的方式運行,可以通過該配置項修改,使用yes啟用守護行程
daemonize yes
2.當Redis以守護行程方式運行時,Redis默認會把pid寫入/var/run/redis.pid檔案,可以通過pidfile指定
pidfile /var/run/redis.pid
3.指定Redis監聽埠,默認埠為6379,作者在自己的一篇博文中解釋了為什么選用6379作為默認埠,因為6379在手機按鍵上MERZ對應的號碼,而MERZ取自意大利歌女Alessia Merz的名字
port 6379
4.系結的主機地址
bind 127.0.0.1
5.當客戶端閑置多長時間后關閉連接,如果指定為0,表示關閉該功能
timeout 300
6.指定日志記錄級別,Redis總共支持四個級別:debug、verbose、notice、warning,默認為verbose
loglevel verbose
7.日志記錄方式,默認為標準輸出,如果配置Redis為守護行程方式運行,而這里又配置為日志記錄方式為標準輸出,則日志將會發送給/dev/null
logfile stdout
8.設定資料庫的數量,默認資料庫為0,可以使用SELECT 命令在連接上指定資料庫id
databases 16
9.指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合
save seconds changes
Redis默認組態檔中提供了三個條件:
save 900 1
save 300 10
save 60 10000
分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改,
10.指定存盤至本地資料庫時是否壓縮資料,默認為yes,Redis采用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導致資料庫檔案變的巨大
rdbcompression yes
11.指定本地資料庫檔案名,默認值為dump.rdb
dbfilename dump.rdb
12.指定本地資料庫存放目錄
dir ./
13.設定當本機為slav服務時,設定master服務的IP地址及埠,在Redis啟動時,它會自動從master進行資料同步
slaveof <masterip> <masterport>
14.當master服務設定了密碼保護時,slav服務連接master的密碼
masterauth <master-password>
15.設定Redis連接密碼,如果配置了連接密碼,客戶端在連接Redis時需要通過AUTH <password>命令提供密碼,默認關閉
requirepass foobared
16.設定同一時間最大客戶端連接數,默認無限制,Redis可以同時打開的客戶端連接數為Redis行程可以打開的最大檔案描述符數,如果設定 maxclients 0,表示不作限制,當客戶端連接數到達限制時,Redis會關閉新的連接并向客戶端回傳max number of clients reached錯誤資訊
maxclients 128
17.指定Redis最大記憶體限制,Redis在啟動時會把資料加載到記憶體中,達到最大記憶體后,Redis會先嘗試清除已到期或即將到期的Key,當此方法處理 后,仍然到達最大記憶體設定,將無法再進行寫入操作,但仍然可以進行讀取操作,Redis新的vm機制,會把Key存放記憶體,Value會存放在swap區
maxmemory <bytes>
18.指定是否在每次更新操作后進行日志記錄,Redis在默認情況下是異步的把資料寫入磁盤,如果不開啟,可能會在斷電時導致一段時間內的資料丟失,因為 redis本身同步資料檔案是按上面save條件來同步的,所以有的資料會在一段時間內只存在于記憶體中,默認為no
appendonly no
19.指定更新日志檔案名,默認為appendonly.aof
appendfilename appendonly.aof
20.指定更新日志條件,共有3個可選值:
no:表示等作業系統進行資料快取同步到磁盤(快)
always:表示每次更新操作后手動呼叫fsync()將資料寫到磁盤(慢,安全)
everysec:表示每秒同步一次(折衷,默認值)
appendfsync everysec
21.指定是否啟用虛擬記憶體機制,默認值為no,簡單的介紹一下,VM機制將資料分頁存放,由Redis將訪問量較少的頁即冷資料swap到磁盤上,訪問多的頁面由磁盤自動換出到記憶體中(在后面的文章我會仔細分析Redis的VM機制)
vm-enabled no
22.虛擬記憶體檔案路徑,默認值為/tmp/redis.swap,不可多個Redis實體共享
vm-swap-file /tmp/redis.swap
23.將所有大于vm-max-memory的資料存入虛擬記憶體,無論vm-max-memory設定多小,所有索引資料都是記憶體存盤的(Redis的索引資料 就是keys),也就是說,當vm-max-memory設定為0的時候,其實是所有value都存在于磁盤,默認值為0
vm-max-memory 0
24.Redis swap檔案分成了很多的page,一個物件可以保存在多個page上面,但一個page上不能被多個物件共享,vm-page-size是要根據存盤的 資料大小來設定的,作者建議如果存盤很多小物件,page大小最好設定為32或者64bytes;如果存盤很大大物件,則可以使用更大的page,如果不 確定,就使用默認值
vm-page-size 32
25.設定swap檔案中的page數量,由于頁表(一種表示頁面空閑或使用的bitmap)是在放在記憶體中的,,在磁盤上每8個pages將消耗1byte的記憶體,
vm-pages 134217728
26.設定訪問swap檔案的執行緒數,最好不要超過機器的核數,如果設定為0,那么所有對swap檔案的操作都是串行的,可能會造成比較長時間的延遲,默認值為4
vm-max-threads 4
27.設定在向客戶端應答時,是否把較小的包合并為一個包發送,默認為開啟
glueoutputbuf yes
28.指定在超過一定的數量或者最大的元素超過某一臨界值時,采用一種特殊的哈希演算法
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
29.指定是否激活重置哈希,默認為開啟(后面在介紹Redis的哈希演算法時具體介紹)
activerehashing yes
30.指定包含其它的組態檔,可以在同一主機上多個Redis實體之間使用同一份組態檔,而同時各個實體又擁有自己的特定組態檔
include /path/to/local.conf
7.Redis的持久化
7.1RDB(Redis DataBase)
7.1.1RDB介紹
在指定的時間間隔內將記憶體中的資料集快照寫入磁盤,也就是行話講的Snapshot快照,它恢復時是將快照檔案直接讀到記憶體里;
RDB保存的是dump.rdb檔案;
Redis會單獨創建(fork)一個子行程來進行持久化,會先將資料寫入到一個臨時檔案中,待持久化程序都結束了,再用這個臨時檔案替換上次持久化好的檔案,整個程序中,主行程是不進行任何IO操作的,這就確保了極高的性能如果需要進行大規模資料的恢復,且對于資料恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效,RDB的缺點是最后一次持久化后的資料可能丟失;
fork:復制一個與當前行程一樣的行程,新行程的所有資料(變數、環境變數、程式計數器等)數值都和原行程一致,但是是一個全新的行程,并作為原行程的子行程;
7.1.2如何觸發RDB快照
組態檔中默認的快照配置(冷拷貝后重新使用:可以cp dump.rdb dump_new.rdb);
使用命令save或者bgsave
save:save時只管保存,其它不管,全部阻塞;
bgsave:Redis會在后臺異步進行快照操作,快照同時還可以回應客戶端請求,可以通過lastsave命令獲取最后一次成功執行快照的時間;
執行flushall命令,也會產生dump.rdb檔案,但里面是空的,無意義;
7.1.3如何恢復
將備份檔案 (dump.rdb) 移動到 redis 安裝目錄并啟動服務即可,通過config get dir可獲取目錄;
7.1.4如何停止
動態所有停止RDB保存規則的方法:redis-cli config set save "";
7.1.5優勢
適合大規模的資料恢復;
對資料完整性和一致性要求不高;
7.1.6劣勢
在一定間隔時間做一次備份,所以如果redis意外宕掉的話,就會丟失最后一次快照后的所有修改;
fork的時候,記憶體中的資料被克隆了一份,大致2倍的膨脹性需要考慮;
7.2AOF(Append Only File)
7.2.1AOF介紹
以日志的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加檔案但不可以改寫檔案,redis啟動之扯訓讀取該檔案重新構建資料,換言之,redis重啟的話就根據日志檔案的內容將寫指令從前到后執行一次以完成資料的恢復作業(AOF保存的是appendonly.aof檔案);
AOF啟動/修復/恢復
1.正常恢復
啟動:修改默認的appendonly no,改為yes;
將有資料的aof檔案復制一份保存到對應目錄(目錄通過config get dir命令獲取);
恢復:重啟redis然后重新加載;
2.例外恢復
啟動:修改默認的appendonly no,改為yes;
備份被破壞的aof檔案;
修復:使用redis-check-aof --fix命令進行修復;
恢復:重啟redis然后重新加載;
7.2.2rewrite
1.rewrite介紹
AOF采用檔案追加方式,檔案會越來越大為避免出現此種情況,新增了重寫機制,當AOF檔案的大小超過所設定的閾值時,Redis就會啟動AOF檔案的內容壓縮,只保留可以恢復資料的最小指令集.可以使用命令bgrewriteaof;
2.重寫原理
AOF檔案持續增長而過大時,會fork出一條新行程來將檔案重寫(也是先寫臨時檔案最后再rename),遍歷新行程的記憶體中資料,每條記錄有一條的Set陳述句,重寫aof檔案的操作,并沒有讀取舊的aof檔案,而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的aof檔案,這點和快照有點類似;
3.觸發機制
Redis會記錄上次重寫時的AOF大小,默認配置是當AOF檔案大小是上次rewrite后大小的一倍且檔案大于64M時觸發;
7.2.3優勢
每修改同步:appendfsync always 同步持久化,每次發生資料變更會被立即記錄到磁盤 性能較差但資料完整性比較好;
每秒同步:appendfsync everysec 異步操作,每秒記錄,如果一秒內宕機,有資料丟失;
不同步:appendfsync no 從不同步;
7.2.4劣勢
相同資料集的資料而言aof檔案要遠大于rdb檔案,恢復速度慢于rdb;
aof運行效率要慢于rdb,每秒同步策略效率較好,不同步效率和rdb相同;
7.3總結(Which One)
1.RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照存盤;
2.AOF持久化方式記錄每次對服務器寫的操作,當服務器重啟的時候會重新執行這些命令來恢復原始的資料,AOF命令以redis協議追加保存每次寫的操作到檔案末尾,Redis還能對AOF檔案進行后臺重寫,使得AOF檔案的體積不至于過大;
3.只做快取:如果你只希望你的資料在服務器運行的時候存在,你也可以不使用任何持久化方式;
4.同時開啟兩種持久化方式
在這種情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料,因為在通常情況下AOF檔案保存的資料集要比RDB檔案保存的資料集要完整;
同時使用兩者時服務器重啟也只會找AOF檔案,那要不要只使用AOF呢?作者建議不要,因為RDB更適合用于備份資料庫(AOF在不斷變化不好備份),快速重啟,而且不會有AOF可能潛在的bug,留著作為一個萬一的手段,
5.性能建議
因為RDB檔案只用作后備用途,建議只在Slave上持久化RDB檔案,而且只要15分鐘備份一次就夠了,只保留save 900 1這條規則,
如果Enalbe AOF,好處是在最惡劣情況下也只會丟失不超過兩秒資料,啟動腳本較簡單只load自己的AOF檔案就可以了,代價一是帶來了持續的IO,二是AOF rewrite的最后將rewrite程序中產生的新資料寫到新檔案造成的阻塞幾乎是不可避免的,只要硬碟許可,應該盡量減少AOF rewrite的頻率,AOF重寫的基礎大小默認值64M太小了,可以設到5G以上,默認超過原大小100%大小時重寫可以改到適當的數值,
如果不Enable AOF ,僅靠Master-Slave Replication 實作高可用性也可以,能省掉一大筆IO也減少了rewrite時帶來的系統波動,代價是如果Master/Slave同時倒掉,會丟失十幾分鐘的資料,啟動腳本也要比較兩個Master/Slave中的RDB檔案,載入較新的那個,新浪微博就選用了這種架構;
8.Redis的事務
8.1redis事務簡介
可以一次執行多個命令,本質是一組命令的集合,一個事務中的所有命令都會序列化,按順序地串行化執行而不會被其它命令插入,不許加塞;
8.2redis事務能干什么
一個佇列中,一次性、順序性、排他性的執行一系列命令;
8.3redis事務執行五種情況
case1:正常執行 執行exec全部成功;
case2:放棄事務 執行discard;
case3:全體連坐 在向事物佇列中添加命令的時候報錯,然后執行exec會全部失敗;
case4:冤頭債主 在向事物佇列中添加命令的時候沒有報錯,但在執行exec的時候某一條命令執行失敗,只會影響這一個,其他的會執行成功,這種為部分成功;
case5:watch監控
Redis部分支持事務
8.4悲觀鎖/樂觀鎖/CAS(Check And Set)
8.4.1悲觀鎖
悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖,
傳統的關系型資料庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖,
8.4.2樂觀鎖
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制,樂觀鎖適用于多讀的應用型別,這樣可以提高吞吐量,
CAS(Check And Set)
witch命令可以為 Redis 事務提供 check-and-set (CAS)行為,類似樂觀鎖,
被 witch的鍵會被監視,并會發覺這些鍵是否被改動過了, 如果有至少一個被監視的鍵在 exec執行之前被修改了,那么整個事務都會被取消,exec回傳空多條批量回復(null multi-bulk reply)來表示事務已經失敗,
8.5redis事務執行的程序
開啟:以multi開始一個事務;
入隊:將多個命令入隊到事務中,接到這些命令并不會立即執行,而是放到等待執行的事務佇列里面;
執行:由exec命令觸發事務;
8.6redis事務的特性
1.單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行,事務在執行的程序中,不會被其他客戶端發送來的命令請求所打斷;
2.沒有隔離級別的概念:佇列中的命令沒有提交之前都不會實際的被執行,因為事務提交前任何指令都不會被實際執行,也就不存在”事務內的查詢要看到事務里的更新,在事務外查詢不能看到”這個讓人萬分頭痛的問題;
3.不保證原子性:redis同一個事務中如果有一條命令執行失敗,其后的命令仍然會被執行,沒有回滾;
9.Redis的復制(Master | Slave)
9.1Redis復制簡介
行話:也就是我們所說的主從復制,主機資料更新后根據配置和策略,自動同步到備機的master/slaver機制,master以寫為主,slave以讀為主;
9.2Redis的復制能干什么
- 讀寫分離;
- 容災恢復;
9.3Redis復制如何去應用
1.配從(庫)不配主(庫);
2.從庫配置:執行命令slaveof 主庫IP 主庫埠:
每次與master斷開之后,都需要重新連接,除非你配置進redis.conf檔案;
執行命令info replication查看主從關系;
3.修改組態檔細節操作:
拷貝多個redis.conf檔案;
開啟daemonize yes;
修改pid檔案名字;
修改指定埠;
修改log檔案名字;
修改dump.rdb名字;
4.常用三招
一主多仆
一個master兩個slave;
一些問題?
(1) 切入點問題?slave1、slave2是從頭開始復制還是從切入點開始復制?
答:從頭開始復制;
(2) 從機是否可以寫?set可否?
答:從機不可以寫,也就不能set;
(3) 主機shutdown后情況如何?從機是上位還是原地待命?
答:原地待命;
(4) 主機又回來了后,主機新增記錄,從機還能否順利復制?
答:可以;
(5) 其中一臺從機宕掉后情況如何?恢復它能跟上主機嗎?
答:不能,需要重新建立主從關系;
薪火相傳
上一個Slave可以是下一個slave的Master,Slave同樣可以接收其他slaves的連接和同步請求,那么該slave作為了鏈條中下一個的master,可以有效減輕master的寫壓力,
中途變更轉向:會清除之前的資料,重新建立拷貝最新的,
反客為主
主機宕掉后,從機升級為主機:
選擇一個從機手動執行slaveof no one命令變更為主機,其他從機與該主機建立主從關系,
9.4Redis復制的原理
master接到命令啟動后臺的存盤行程,同時收集所有接收到的用于修改資料集命令,在后臺行程執行完畢之后,master將傳送整個資料檔案到slave,以完成一次完全同步
全量復制:而slave服務在接收到資料庫檔案資料后,將其存盤并加載到記憶體中,slave第一次同步為全量復制,
增量復制:master繼續將新的所有收集到的修改命令依次傳給slave,完成同步
但是只要是重新連接master,第一次完全同步(全量復制)將被自動執行,
9.5哨兵模式(sentinel)
哨兵模式簡介
反客為主的自動版,能夠后臺監控主機是否故障,如果故障了根據投票數自動將從庫轉換為主庫;
啟動哨兵模式步驟:
1.自定義的/myredis目錄下新建sentinel.conf檔案,名字絕不能錯;
2.配置哨兵,填寫內容在sentinel.conf檔案中配置:
sentinel monitor 被監控資料庫名字(自己起個名字) 127.0.0.1 6379 1
上面最后一個數字1,表示主機掛掉后salve投票看讓誰接替成為主機,得票數多的成為主機;
3.啟動哨兵
執行命令:redis-sentinel /myredis/sentinel.conf (目錄依照各自的實際情況配置,可能目錄不同);
問題
如果之前的master重啟回來,會不會雙master沖突?
不會造成雙沖突,之前的master會成為slave,
9.6復制的缺點
復制延時
由于所有的寫操作都是先在Master上操作,然后同步更新到Slave上,所以從Master同步到Slave機器有一定的延遲,當系統很繁忙的時候,延遲問題會更加嚴重,Slave機器數量的增加也會使這個問題更加嚴重,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/5533.html
標籤:其它
