? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Redis 初 級 精 講
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 原創(chuàng)者:文思
I:Redis前轉(zhuǎn)
一餐蔬、軟件系統(tǒng)的演變
1998-2008:單機mysql時代(MyISUM引擎[表鎖]-->InnoDB引擎[行鎖])—>Memached+mysql+垂直拆分—>mysql主從分離à分表分庫+集群
瓶頸:
1衣摩、數(shù)據(jù)總量大小澜术,當(dāng)一臺機器放不下時
2巩搏、 數(shù)據(jù)索引(B+Tree)锅锨,當(dāng)一臺機器內(nèi)存放不下時
3暑诸、 訪問量(讀寫混合或分離)余赢,當(dāng)一個實例不能承受時
MySQL數(shù)據(jù)庫也經(jīng)常存儲一些大文本字段宿稀,導(dǎo)致數(shù)據(jù)庫表非常的大寥裂,在做數(shù)據(jù)庫恢復(fù)的時候就導(dǎo)致非常的慢嵌洼,不容易快速恢復(fù)數(shù)據(jù)庫。比如1000萬4KB大小的文本就接近40GB的大小封恰,如果能把這些數(shù)據(jù)從MySQL省去麻养,MySQL將變得非常的小。關(guān)系數(shù)據(jù)庫很強大俭驮,但是它并不能很好的應(yīng)付所有的應(yīng)用場景回溺。MySQL的擴展性差(需要復(fù)雜的技術(shù)來實現(xiàn)),大數(shù)據(jù)下IO壓力大混萝,表結(jié)構(gòu)更改困難遗遵,正是當(dāng)前使用MySQL的開發(fā)人員面臨的問題。
2008年以后互聯(lián)網(wǎng)飛速發(fā)展的時代逸嘀,其應(yīng)用的特點是3V+3高:
海量volume,多樣variety,實時velocity
高并發(fā)车要,高可擴,高性能
互聯(lián)網(wǎng)公司的應(yīng)用架構(gòu)越來越微服務(wù)化:
互聯(lián)網(wǎng)時代背景下崭倘,大數(shù)據(jù)量翼岁、高并發(fā),頻發(fā)讀寫數(shù)據(jù)庫壓力大司光,多數(shù)據(jù)源琅坡,多數(shù)據(jù)類型。而常見關(guān)系型數(shù)據(jù)庫難以滿足需求残家,所以NoSql的興起榆俺。
以淘寶女裝為例:
1、商品基本信息坞淮。(傳統(tǒng)關(guān)系型數(shù)據(jù)庫類)
2茴晋、商品描述、詳情回窘、評價信息诺擅、多文字類(1000萬條基本上很多個G了,一般用MongDB)
3啡直、商品圖片烁涌。(靜態(tài)服務(wù)器)
4苍碟、商品的關(guān)鍵字。(Isearch)
5烹玉、 商品波段性的熱點高頻詞匯信息驰怎。(內(nèi)存數(shù)據(jù)庫如:Redis)
6、 商品的交易二打、價格計算县忌、積分累計。(支付寶及第三方支付接口)
系統(tǒng)中針對多數(shù)據(jù)源继效、多數(shù)據(jù)類型症杏、數(shù)據(jù)源改造而數(shù)據(jù)服務(wù)平臺不需要大面積重構(gòu)這種需求成為主要應(yīng)用場景。
解決:UDSL統(tǒng)一數(shù)據(jù)平臺瑞信。在此不作詳細描述厉颤。
為解決以上需求,NoSql數(shù)據(jù)模型興起凡简,已成為大中型互聯(lián)網(wǎng)公司的標(biāo)配架構(gòu)之一逼友。
二、NoSql數(shù)據(jù)模型的興起
當(dāng)前模式:sql + nosql
Not Only Sql非關(guān)系型數(shù)據(jù)庫秤涩。
NoSql如何設(shè)計:
{
? "customer":{
????? "id":1136,
????? "name":"zhangsan",
?????"billingAddress":[{"city":"BeiJing"}],
????? "orders":[
??????????????????????????????? {"id":"123","name":"巧克力"},
?????????????? {"id":"456","name":"牛肉"},
??????????????????????????????? {"id":"789","name":"黃金"}
?????? ],
????? ......
?? }
}
大并發(fā)場景下傳統(tǒng)sql層設(shè)計原則:
傳統(tǒng)關(guān)系型數(shù)據(jù)庫高并發(fā)的操作強烈不建議有關(guān)聯(lián)查詢帜乞;
適當(dāng)允許冗余數(shù)據(jù)來避免關(guān)聯(lián)查詢;
分布式事務(wù)支持不了太多并發(fā)筐眷。
如果按BSON這種數(shù)據(jù)格式存儲的進行查詢黎烈,就能避免如上問題,如根據(jù)id=1136就可避免數(shù)據(jù)庫關(guān)聯(lián)查詢匀谣,而查出數(shù)據(jù)格式為BSON格式的所有信息字符串照棋。
NoSql的聚合模型:
1、K-V:代表redis
2武翎、文檔型數(shù)據(jù)庫(數(shù)據(jù)模型是BSON):代表MongDB。BSON是類似json的二進制存儲格式宝恶。
3膏执、列存儲數(shù)據(jù)庫(列族):代表Hbase征峦。按列存儲數(shù)據(jù)消请,即縱向的K-V栏笆,列縱向擴展。如:
name:”zhangsan”
billingAddress:….
4臊泰、圖形:放的不是圖形蛉加,是關(guān)系,專注于構(gòu)建關(guān)系圖譜
NoSql特點:
1缸逃、 去關(guān)系型针饥,數(shù)據(jù)之間無關(guān)系,所以易擴展需频。
2丁眼、數(shù)據(jù)模型靈活多樣,無需事先為要存儲的數(shù)據(jù)建立字段昭殉,可隨意增刪字段苞七。
3、強調(diào)最終一致性挪丢,而非ACID
4蹂风、 CAP定理(Consistency強一致性,Availability可用性,Partition tolerance分區(qū)容錯性)
CAP:一個分布式系統(tǒng)不可能同時滿足CAP三種需求,最多只能同時滿足兩個吃靠。
三種組合CA硫眨、CP、AP哪個最重要呢巢块?
常理都是可用性第一(A)礁阁,其次分析C(一致性)和P(分區(qū)容錯性)哪個重要,NoSql時代一般是分布式應(yīng)用族奢,分區(qū)容錯性是必須實現(xiàn)的姥闭,所以AP是互聯(lián)網(wǎng)場景下大多數(shù)網(wǎng)站架構(gòu)的選擇,而CA代表著以前傳統(tǒng)數(shù)據(jù)庫的思想選擇越走。而CP是Redis棚品、MongDB的思想選擇。
BASE:為解決關(guān)系數(shù)據(jù)庫強一致性引起的可用性降低問題而提出的解決方案廊敌。
BasicallyAvailable基本可用
SoftState軟狀態(tài)
EventuallyConsistent最終一致性
互聯(lián)網(wǎng)應(yīng)用架構(gòu)的設(shè)計思想AP+BASE:通過讓系統(tǒng)放松對某一時刻數(shù)據(jù)一致性的要求來換取系統(tǒng)整體伸縮性和性能上的改觀铜跑。
II:Redis初級
一、Redis基礎(chǔ)
1骡澈、安裝
Remote Dictionary Server遠程字典服務(wù)器锅纺,支持將內(nèi)存數(shù)據(jù)異步存儲到硬盤,有類似httpsession設(shè)置定時過期功能肋殴,定時器計數(shù)器囤锉,發(fā)布訂閱消息系統(tǒng)坦弟。
redis.io官網(wǎng)??????????????
怎么玩(以下是此文章學(xué)習(xí)梳理知識點的順序方向):
1、數(shù)據(jù)類型官地、基本操作和配置
2酿傍、持久化和復(fù)制,RDB/AOF
3驱入、事務(wù)的控制
4赤炒、復(fù)制(哨兵模式)
安裝……略,redis.conf配置文件(重要)
啟動:redis-servier?/redis-3.2.1/redis.conf
啟動客戶端:redis-cli?–p?6379????????
Ping得到pong說明連接成功:
set?k1?hello
get?k1
得到hello說明功能ok:
Redis是單進程的。
2亏较、Redis.conf詳講
port 6379是配置啟動端口的地方可霎,默認(rèn)是6379:
默認(rèn)創(chuàng)建16個數(shù)據(jù)庫,并且可以選擇宴杀,database:
通過select命令切換數(shù)據(jù)庫癣朗,分庫的作用主要用來業(yè)務(wù)分片:
dbsize查看當(dāng)前數(shù)據(jù)庫的key的數(shù)量:
flushdb清除當(dāng)前庫所有key(當(dāng)前庫):
flushall清除所有庫中的key,慎用旺罢。Redis的索引都是從0開始旷余。
3、Redis五大數(shù)據(jù)類型:
1扁达、String
2正卧、 Hash
3、 List
4跪解、 Set
5炉旷、Sorted set
??? String是redis中基本的數(shù)據(jù)類型,是二進制安全的叉讥,所以可以包含任何數(shù)據(jù)窘行,比如圖片或者序列化對象,一個字符串value最多可以是512M
??? Hash哈希是一個鍵值對集合图仓,是一個String類型的fieldhevalue的映射表罐盔,特別適合用于存儲對象。類似java里面的Map
??? List列表是簡單的字符串列表救崔,按照插入順序排序惶看。
??? Set集合是String類型的無序集合,它通過HashTablelai實現(xiàn)的
??? Sorted set有序集合六孵,和set不同的是每個元素都會關(guān)聯(lián)一個double類型的分?jǐn)?shù)纬黎,通過分?jǐn)?shù)值來為成員進行從小到大的排序。
4劫窒、常用命令:
1)和key相關(guān)的常用命令:set本今、get、exists key
set、get略
exists
key判斷一個key是否存在:
根據(jù)命令可以推出jedis的api參數(shù)及返回值
move移動key從當(dāng)前庫到目標(biāo)庫诈泼,move? keyname?targetBD:
以上演示了:0號庫有k1,k2,k3三個key,通過move移動k3到1號庫煤禽。
expire key設(shè)置key的過期時間铐达。ttl key代表查看還有多少秒過期,-1代表永不過期檬果,-2代表已過期:
使用expire設(shè)置k1過期時間為10秒后然后ttl查看:
10秒后k1就不存在了瓮孙,已過期就自動從內(nèi)存系統(tǒng)中移除。
type key查看key的類型:
2)和String相關(guān)的常用命令:
set/get/del/append/strlen
set設(shè)置相同的key选脊,前一個會被后一個覆蓋:
其它命令略杭抠。
Incr/decr/incrby/decrby,一定要是數(shù)字才能進行加減:
Incr每次遞增1
Incrby可以指定遞增的數(shù)值
decrby遞減恳啥,略偏灿。
setex(set with expire)設(shè)置值并加過期時間setex 過期時間值:
setnx(set if not exist),key不存在時才進行set:
批量操作mset/mget/msetnx:
3)和List相關(guān)的常用命令:
Lpush/rpush/lrang
lpush是后進先出排序方式钝的,rpush是先進先出排序方式翁垂。
lpip/rpop是一個一個移出:
lindex按下標(biāo)取元素:
lrem刪除:
ltrim截取list:ltrim? key?startindex? endindex,演示略硝桩。
pop與push的組合應(yīng)用:
linsert命令:linsert? key?before/after? 值1 值2
總結(jié):如果值全部移除沿猜,對應(yīng)的鍵也就消失了,鏈表從頭插入效率高碗脊,中間效率很慢啼肩。
3)set常用命令:
sadd/smembers/sismember
上圖可以體現(xiàn)出set有序但不允許重復(fù)值。
scard獲取集合里元素個數(shù),srem? key?value刪除集合中元素衙伶。
sdiff差集/sinter交集/sunion并集:
3)hash常用命令:
hset/hget/hmset/hmget/hgetall/hdel
Hexists?key在key里面的某個值的key是否存在:
Hkeys/hvals里面的全部key/value:
Hincrby/hincrbyfloat:
5)zset常用命令:
先回憶一下zset定義: Sorted set有序集合祈坠,和set不同的是每個元素都會關(guān)聯(lián)一個double類型的分?jǐn)?shù),通過分?jǐn)?shù)值來為成員進行從小到大的排序矢劲。
zadd/zrang,通過定義來推測可能要比set命令多一個double分?jǐn)?shù)類型的參數(shù):
zcard/zcount key score/zrank key values等命令颁虐。
5、解析Redis配置文件redis.conf:
1)單元:單位定義卧须,大小寫不敏感
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
2)包含另绩,支持配置文件外置化,incolud包含進來外置化的配置
# include
.\path\to\local.conf
# include
c:\path\to\other.conf
3)GENERAL標(biāo)準(zhǔn)化配置
daemonize:
出廠默認(rèn)是no花嘶,改成daemonize yes
Redis默認(rèn)不是以守護進程的方式運行的笋籽,修改此參數(shù),啟用守護進行運行椭员。
pidfile:
進程管道pip文件车海,當(dāng)運行起來時并沒有指定其它路徑時,將在此路徑下產(chǎn)生。
port是啟動端口侍芝,就不用細說研铆。
tcp-backlog:
tcp-backlog 511
設(shè)置tcp的backlog,backlog是一個連接隊列州叠,在高并發(fā)環(huán)境下需要一個高的backlog值來避免慢客戶端連接問題棵红。
bind:
綁定的一些端口設(shè)備:
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1
?? timeout:
# Close the connection after a client isidle for N seconds (0 to disable)連接超時設(shè)置:
timeout 0????
代表客戶端閑置多久后關(guān)閉連接,0代表一直不關(guān)閉
??? tcp-keepalive:??
??? # TCP keepalive.是否進行keepalive心跳檢測咧栗,建議設(shè)置成60秒:
??? tcp-keepalive 0
? loglevel:
? ?# Specify the server verbosity level.
# This can be one of:日志級別及選擇
# debug (a lot of information, useful fordevelopment/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / criticalmessages are logged)
?loglevel?notice
syslog-enabled:
是否把日志輸出到syslog中
syslog-ident:
指定syslog里的日志標(biāo)志
?? Redis默認(rèn)的數(shù)據(jù)庫個數(shù):?????
?? # Set the number of databases. The defaultdatabase is DB 0, you can select
?? # a different one on a per-connection basisusing SELECT where
? # dbid is a number between 0 and'databases'-1
databases 16
4)SNAPSHOTTING快照
dbfilename:指定本地數(shù)據(jù)庫文件名
dbfilename dump.rdb
dir:指定本地數(shù)據(jù)庫存放目錄
dir ./
5)SECURITY安全???
redis默認(rèn)空密碼逆甜,使用config get命令查看
使用config get命令查看啟動路徑
同理,config set 是一些常用配置的設(shè)置致板,比如設(shè)置密碼:config set requirepass “123456”或者requirepass “123456”交煞。配制后客戶端連接redis時需要通過AUTH命令提供密碼。
6)LIMIT限制
Maxclients:最大連接數(shù)限制
# Set the max number of connected clientsat the same time. By default
# this limit is set to 10000 clients當(dāng)沒有設(shè)置時會默認(rèn)10000
Maxmemory:最大內(nèi)存斟或。vm-max-memory設(shè)置為0時(默認(rèn)值0)素征,Key存放在內(nèi)存,value存放在swap區(qū)萝挤。
Maxmemory-policy:達到最大內(nèi)促后稚茅,緩存過期清潔策略
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
?# is reached. You can select among fivebehaviors:
# (根據(jù)lru算法先進先出,只對設(shè)置了過期時間的鍵有效)volatile-lru:remove the key with an expire set using an LRU algorithm
# (根據(jù)lru算法最近最少使用)allkeys-lru:remove any key according to the LRU algorithm
# (在過期集合中移除隨機key,只對設(shè)置了過期時間的鍵有效)volatile-random:remove a random key with an expire set
# (隨機)allkeys-random :remove a random key, any key
#(有限時間內(nèi),移除那些TTL值最小的key,ttl最小代表最近要過期)volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# (永不過期)noeviction:don't expire at all, just return an error on write operations
# The default is:
# maxmemory-policy volatile-lru
生產(chǎn)環(huán)境一定不要設(shè)置成永不過期
Maxmemory-samples:設(shè)置樣本數(shù)量平斩,LRU算法和最小TTL算法都并非十分精確亚享,而是估值,所以可以設(shè)置樣本大小,redis默認(rèn)會從樣本數(shù)量中選擇進行測試出估值绘面。
二欺税、Redis持久化
RDB(RedisDataBase)、AOF(Append Only File)
如果大規(guī)模數(shù)據(jù)恢復(fù)揭璃,且對數(shù)據(jù)恢復(fù)的完整性不敏感晚凿,rdb要比aof高效,但rdb缺點是最后一次的持久化數(shù)據(jù)可能丟失瘦馍。
RDB:在指定的時間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照(snapshot快照)寫入磁盤歼秽,它恢復(fù)時是將快照文件直接讀到內(nèi)存中。
Redis會創(chuàng)建一個子進程來進行持久化情组,整個過程中主進程不進行任何IO操作燥筷。
內(nèi)部原理:fork的作用是復(fù)制一個與當(dāng)前進程一樣的進程,新進程的所有數(shù)據(jù)數(shù)都和原進程一致院崇,此進程作為原進程的子進程肆氓。隱患是當(dāng)內(nèi)存數(shù)據(jù)很大很慢時會更慢,需考慮內(nèi)存空間底瓣。
SNAPSHOTTING中:
#?? Will save the DB if both the given number ofseconds and the given
#?? number of write operations against the DBoccurred.
#?? In the example below the behaviour will beto save:
#?? after 900 sec (15 min) if at least 1 keychanged(900秒內(nèi)只要有1個改變)
#?? after 300 sec (5 min) if at least 10 keyschanged(300秒內(nèi)只要有10個改變)
#?? after 60 sec if at least 10000 keys changed(00秒內(nèi)只要有10000個改變)
save 900 1
save 300 10
save 60 10000
滿足上述三種條件之一當(dāng)停止服務(wù)時就會觸發(fā)reids持久化丛版。用法:save <秒> <寫操作次數(shù)>
# The filename
where to dump the DB
dbfilename
dump.rdb備份文件所在地
模擬生產(chǎn)運維操作:現(xiàn)在進行三分鐘內(nèi)(300秒)內(nèi)變更10次以上:
這時可以看到磁盤下生成了dump.rdb文件
將dump.rdb重命名為dump_bak.rdb丙笋,并刪除dump.rdb(模擬生產(chǎn)運維流程)闭专。因為配置中dump.rdb是備份文件,所以再啟動時無法恢復(fù)凳鬓。
再次啟動并清除所有key:
將dump_bak.rdb重命名恢復(fù)成dum.rdb,并且重啟redis:
看到所有的key都已經(jīng)恢復(fù)患民。
或者執(zhí)行save命令也可以立刻執(zhí)行快照持久化缩举,但此操作會在持久化時把其它操作全部阻塞,慎用或者夜晚用戶低谷時使用酒奶。
bgsave:后臺異步進行快照持久化,同時快照還可以執(zhí)行其它操作奶赔。
Stop –writes-on-bgsave-error命令:當(dāng)進行持久化save出錯時前端禁止寫入數(shù)據(jù)惋嚎。
Stop –writes-on-bgsave-error
yes,如果配置成no表示你不在乎數(shù)據(jù)不一致或者有其它手段發(fā)現(xiàn)和控制站刑。
Rdbcompression:對于存儲到磁盤中的快照另伍,是否采用lzf算法進行壓縮,壓縮消費cpu但節(jié)省空間绞旅。使用原則:一般能用錢解決的事情不要去消耗性能摆尝,所以建議設(shè)置成no。
Rdbchecksum:存儲快照后是否采用crc64算法進行數(shù)據(jù)校驗因悲,但這樣會增加大約10%的性能消耗堕汞,建議關(guān)閉此功能。
AOF:
rdb存在的前提下為何要存在aof晃琳,以此思考rdb劣勢讯检。
aof以日志的形式來記錄每一個寫操作,將redis執(zhí)行過的所有寫指令記錄下來卫旱,只許追加文件人灼,但不可改寫文件。Redis啟動之初會讀取該文件重新構(gòu)建數(shù)據(jù)顾翼。
查看配置文件中APPEND ONLY MODE:
此配置默認(rèn)是關(guān)appendonly?no
現(xiàn)在改成yes:
既然appendonly.aof記錄的是執(zhí)行命令投放,那服務(wù)器突然斷電的時候,很可能記錄的命令不完整适贸。那么再啟動時是否可以啟動成功灸芳?沒有啟動成功。
而且將dump_bak.rdb恢復(fù)成dum.rdb再次啟動還沒有成功拜姿,說明當(dāng)rdb與aof同時存在使用時耗绿,優(yōu)先使用加載aof。
運行redis-check-aof:
再次啟動成功砾隅。
redis-check-aof:解決網(wǎng)絡(luò)閃斷误阻、延時、病毒、丟包等引起的aof不完整問題究反。具體用法請百度寻定。
aof相關(guān)策略:
Always:同步持久化,每次發(fā)生數(shù)據(jù)變更立刻記錄到磁盤精耐,性能較差狼速。
Everysec:出廠默認(rèn)推薦,異步操作卦停,每秒記錄向胡,會丟失一秒內(nèi)數(shù)據(jù)。
No:不進行
總結(jié)異尘辏恢復(fù)步驟:
1僵芹、啟動:設(shè)置yes
2、 備份被寫壞的aof文件
3小槐、修復(fù):redis-check-aof–fix進行修復(fù)
4拇派、恢復(fù):重啟redis然后重新加載
Rewrite:aof采用文件追加方式,文件會越來越大凿跳,為避免此情況件豌,新增了重寫機制,當(dāng)aof文件的大小超過所設(shè)定的閥值時控嗜,redis會啟動aof內(nèi)容壓縮茧彤,只保留可以恢復(fù)數(shù)據(jù)的最小指令集,可以使用命令bgrewriteaof
觸發(fā)機制:
# Specify a
percentage of zero in order to disable the automatic AOF
# rewrite feature.
auto-aof-rewrite-percentage100 重寫的基準(zhǔn)值
auto-aof-rewrite-min-size 64mb重寫的基準(zhǔn)值
redis會記錄上次文件重寫時的aof大小疆栏,默認(rèn)配置是當(dāng)aof文件大小是上次rewrite后大小的一倍且文件大于64M時觸發(fā)棘街。但是高速發(fā)展的互聯(lián)網(wǎng)公司里3G是起步配置,重寫策略一定要配承边。
aof優(yōu)勢:略
劣勢:相同數(shù)據(jù)集數(shù)據(jù)aof文件遠大于rdb遭殉,恢復(fù)速度慢;aof運行效率慢于rdb博助。
客戶端--命令à服務(wù)器—網(wǎng)絡(luò)協(xié)議命令內(nèi)容àaof文件
總結(jié):
官網(wǎng)建議如果對數(shù)據(jù)敏感和完整性要求不高使用rdb险污。只做緩存的話可以不使用任何持久化方式。也可以同時開啟兩種持久化建議富岳。
性能建議:
1蛔糯、因為rgb文件只用作后備用途,建議在slave上持久化rdb文件窖式,而且只要15分鐘備份一次就夠了蚁飒,只保留save?900? 1這一條規(guī)則即可。
2萝喘、如果開了AOF淮逻,好處是在最惡劣的情況下也只會丟失不超過兩秒的數(shù)據(jù)琼懊,啟動腳本簡單。但代價一是帶來的持續(xù)的IO爬早,二是AOF REWRITE的最后將rewrite過程中產(chǎn)生的新數(shù)據(jù)寫到文件造成的阻塞不可避免哼丈,只要硬盤許可,應(yīng)盡量減少AOF rewrite的頻率筛严,同時默認(rèn)的64M太小醉旦,可以設(shè)置到3或5G以上,默認(rèn)超過原大小100%時重寫可以改到適當(dāng)?shù)臄?shù)據(jù)桨啃。
3车胡、如果沒有開啟AOF,僅靠Master-Slave Replicaiton實現(xiàn)可用也是好的方案照瘾,這樣能省掉大筆IO開銷和rewrite時帶來的波動匈棘。M-S同時倒掉會丟失世紀(jì)分鐘數(shù)據(jù)而已。
三网杆、Redis事務(wù):可以一次執(zhí)行多個命令羹饰,本質(zhì)是一組命令的集合伊滋。
五大案例分類:正常執(zhí)行碳却、放棄事務(wù)、全體連坐笑旺、冤頭債主昼浦、watch監(jiān)控
相關(guān)命令:discard\exec\multi\unwatch\watch?key[key…],根據(jù)英文意思推測命令含義
正常執(zhí)行:
放棄事務(wù):
全體連坐:
冤頭債主:
大家比較全體連坐與冤頭債主,命令都一樣筒主,為何結(jié)果不一樣关噪?是否類似java中的編譯一場與運行時異常?得出結(jié)論:redis對事物的支持是部分支持乌妙,不保證原子性使兔。
WATCH監(jiān)控:
悲觀鎖/樂觀鎖/CAS(check and set)
舉例:初始化信用卡可用余額(100000)和欠款(1000)
以上例子保證兩筆金額在一個事物內(nèi)。但中間有篡改的情況下:
篡改后失敗了藤韵。
watch指令類似樂觀鎖虐沥,事務(wù)提交時,如果key的值已經(jīng)被別的客戶端改變泽艘,整個事務(wù)隊列都不會被執(zhí)行欲险。通過watch命令在事務(wù)執(zhí)行前監(jiān)控多個key,倘若watch之后有任何key的改變匹涮,事務(wù)將不被執(zhí)行天试。
事務(wù)的執(zhí)行過程:開啟-〉入隊-〉執(zhí)行。
四然低、Redis消息訂閱發(fā)布機制:
進程間的一種消息通信模式:發(fā)送者pub發(fā)送消息喜每,訂閱者sub接收消息务唐。
下圖展示了頻道 channel1 ,以及訂閱這個頻道的三個客戶端 ——client2 灼卢、 client5 和 client1 之間的關(guān)系:
當(dāng)有新消息通過 PUBLISH 命令發(fā)送給頻道 channel1 時绍哎, 這個消息就會被發(fā)送給訂閱它的三個客戶端:
發(fā)布命令:publish <管道> <內(nèi)容>
訂閱命令:subscribe<管道>
先訂閱后發(fā)布才能收到消息,可以一次訂閱多個鞋真,比如subscibe c1 c2 c3
通配符形式定義多個用*:psubscribe<*>
示例:
企業(yè)中一般不會使用redis的消息訂閱機制崇堰,所以這里不做詳講。
五涩咖、Redis主從復(fù)制
配置:slaveof? 主庫IP? 主庫端口
可通過以上命令進行配置海诲,但每次與master端口后都需要重新連接,如果寫到redis.conf文件里則不需要斷開后重新手工連接檩互。???????????????????????
常用三招:一主二仆特幔、薪火相傳、反客為主闸昨、哨兵模式
一主二仆示例:
1蚯斯、模擬3臺redis環(huán)境,redis主庫使用原6379端口饵较,兩臺從庫分別使用6380拍嵌、6381端口
2、一主二仆循诉,一臺主機横辆,兩天備機。啟動三臺機器并使用info?replication查看信息
主機set一些key
在6380和6381上設(shè)置從庫茄猫,使用slave 主庫ip 主庫端口
slaveof?127.0.0.1?6379
只要設(shè)置好從機狈蚤,從機會第一次啟動會將主機中所有的key都同步過來。
再使用info? replication看6379:
role:master
connected_slave:2
slave0:ip=127.0.0.1,port=6380,state=online
slave2:ip=127.0.0.1,port=6381,state=online?????
模擬異常:
3划纽、如果在master和slave上都執(zhí)行set操作會怎樣脆侮?
6379:set?k1? 1
6380: set?k1? 11
6381: set? k1? 111???????
6380和6381上無法set:readonly
you cant’t write against a read only slave.
即只有主機才可以寫。
4勇劣、shutdown主機靖避,從機會怎樣?
將6379shutdown芭毙,info replication6380和6381:
6380與6381都仍然是slave筋蓖,master_link_status=down
重啟6379后一切恢復(fù)。
結(jié)論:6380與6379在主機關(guān)閉后會原地待命
5退敦、shutdown從機會怎樣粘咖?
將6380shutdown,然后再啟動后用info replication6380:
Role:master
在6379 set k1 t1后侈百,6380 get k1沒有任何值
結(jié)論:從機配置如沒有配置進redis.conf中瓮下,從機每次重啟都需要重新配置翰铡,否則就是一個獨立的進程應(yīng)用。
如果master下的slave越來越多讽坏,master會越來越累锭魔,所以根據(jù)業(yè)務(wù)場景如果需要可去中心化,這就需要薪火相傳路呜。
薪火相傳示例:
上一個slave可以是下一個slave的master迷捧,slave同樣可以接收其它salve的連接和同步請求,那么該slave作為了鏈條中下一個的master胀葱。
slaveof 新主庫ip 新主庫端口
即:6379(m)->6380(s-m)->6381(s)
在6379:set k1 t1
在6380:slaveof 127.0.0.1 6379
在6381:slaveof 127.0.0.1 6380
中途變更轉(zhuǎn)向:會清除之前的數(shù)據(jù)漠秋,重新建立拷貝最新的。
如果主機掛了抵屿,怎么辦庆锦,這就需要此情況下反客為主。?????
slaveof?no?one使當(dāng)前數(shù)據(jù)庫停止與其它數(shù)據(jù)庫的同步轧葛,轉(zhuǎn)成主庫搂抒。
反客為主示例:
6379:shutdown
6380:slaveof 127.0.0.1 6379
6380:slaveof no one
6381:slaveof 127.0.0.1 6379
再次啟動6379,則6379是獨立的體系了尿扯。
自動化反客為主:哨兵模式
當(dāng)master掛掉后求晶,從slave中投票選擇出新master
1、首先設(shè)置成一主二仆
6380:slaveof 127.0.0.1 6379
6381:slaveof127.0.0.1 6379
2姜胖、6379誉帅、6380淀散、6381下建立sentinel.conf文件
sentinel monitor host6379 127.0.0.1 6379 1
以上配置中最后一個數(shù)字1表示主機掛掉后slave投票看讓誰接替成為主機右莱。
3、6379:shutdown
4档插、稍候6380:info replicaiton查看6380信息
role:master慢蜓,已經(jīng)說明6380被選舉成為了主機。
5郭膛、當(dāng)6379又重啟后info replicaiton查看6379信息
role:slave晨抡,已經(jīng)說明6379重啟回來后只能做從機了。