我的個(gè)人主頁(yè):螞蟻的寶藏
傳統(tǒng)數(shù)據(jù)庫(kù)遵循ACID原則,而NOSQL遵循CAP原則重抖。
Consistency(一致性): 所有節(jié)點(diǎn)在同一時(shí)間具有相同的數(shù)據(jù)
Availability(可用性):集群中一部分節(jié)點(diǎn)失效后同廉,集群整體保證響應(yīng)客服端的讀寫(xiě)請(qǐng)求
Partition tolerance(分區(qū)容災(zāi)性):系統(tǒng)中任意信息的丟失或失敗不會(huì)影響系統(tǒng)繼續(xù)運(yùn)行符衔。
任何時(shí)候奈辰,最多滿(mǎn)足以上兩點(diǎn),在分布式存儲(chǔ)中罗售,分區(qū)容災(zāi)性是必須的辜窑,所以在一致性和可用性上要做出權(quán)衡。redis在一致性上做出了妥協(xié)寨躁,采用結(jié)果最終一致性的弱化處理數(shù)據(jù)異步復(fù)制穆碎。
redis演變
復(fù)制
redis提供復(fù)制功能,用戶(hù)可以通過(guò)復(fù)制master來(lái)創(chuàng)建多個(gè)slave职恳。只要主從服務(wù)器之間通信正常所禀,會(huì)保持相同的數(shù)據(jù),master會(huì)一直將自身的數(shù)據(jù)更新至slave放钦。解決了master的讀壓力色徘。
哨兵
redis sentinel 在分布式系統(tǒng)中,監(jiān)控主從服務(wù)器操禀,在master下線(xiàn)褂策,會(huì)自動(dòng)進(jìn)行故障轉(zhuǎn)移,保證了系統(tǒng)的高可用颓屑。
集群(proxy)
通過(guò)增加proxy層來(lái)進(jìn)行數(shù)據(jù)分片辙培,減輕redis的寫(xiě)壓力。但是proxy層無(wú)法保證高可用邢锯,維護(hù)成本增加。
集群(直連型)
去除proxy層搀别,無(wú)中心架構(gòu)丹擎;通過(guò)選舉制實(shí)現(xiàn)故障轉(zhuǎn)移,完成slave到master的角色轉(zhuǎn)換;節(jié)點(diǎn)可動(dòng)態(tài)擴(kuò)張蒂培;通過(guò)增加slave節(jié)點(diǎn)實(shí)現(xiàn)高可用再愈;數(shù)據(jù)按照slot存儲(chǔ),節(jié)點(diǎn)數(shù)據(jù)可共享护戳。
redis數(shù)據(jù)結(jié)構(gòu)
redis以 key-value 鍵值對(duì) 作為存儲(chǔ)方式翎冲。支持多種數(shù)據(jù)結(jié)構(gòu)。
String
string是redis使用最多的數(shù)據(jù)結(jié)構(gòu)之一媳荒,value大小不能超過(guò)512M抗悍,set的時(shí)候,可以不用引號(hào)钳枕。
值可以是字符串缴渊,整數(shù),浮點(diǎn)數(shù)鱼炒。
若值為數(shù)字衔沼,做運(yùn)算時(shí),redis會(huì)自動(dòng)進(jìn)行轉(zhuǎn)換昔瞧。
命令 | 說(shuō)明 |
---|---|
SET key value | 定義key并賦值 |
GET key | 獲取key的值 |
DEL key | 刪除key |
APPEND key value | 末尾追加指蚁,字符串拼接 |
STRLEN key | 獲取字符串長(zhǎng)度 |
INCR key | 自增 |
DECR key | 自減 |
INCRBY key increment | 按指定步長(zhǎng)增長(zhǎng) |
DECRBY key increment | 按指定步長(zhǎng)減少 |
SETEX key seconds value | 同時(shí)設(shè)置過(guò)期時(shí)間,同EXPIRE自晰,可使用TTL查看剩余時(shí)間 |
List
鏈表上的每個(gè)節(jié)點(diǎn)包含一個(gè)字符串凝化。鏈表的兩端都可以進(jìn)行讀寫(xiě)。
命令 | 說(shuō)明 |
---|---|
LPUSH key value | 向鏈表左端添加元素value |
RPUSH key value | 向鏈表右端添加元素value |
LPOP key | 從鏈表左側(cè)讀取并移除元素 |
RPOP key | 從鏈表右側(cè)讀取并移除元素 |
LINDEX key index | 按index讀取vaule |
LRANGE key start stop | 讀取指定范圍的元素 |
BRPOP key[key ...] timeout | 阻塞的方式從鏈表右側(cè)彈出元素,如果元素為空缀磕,阻塞等待缘圈,直到超時(shí)或者有值返回 |
BLPOP key[key ...] timeout | 阻塞的方式從鏈表右側(cè)彈出元素,如果元素為空,阻塞等待袜蚕,直到超時(shí)或者有值返回 |
Set
無(wú)序且無(wú)重復(fù)的字符串集合
常用命令:
命令 | 說(shuō)明 |
---|---|
SADD key value | 向key中添加元素value糟把,成功返回1,失敗返回0 |
SREM key value | 從key中移除元素value牲剃,成功1遣疯,失敗0 |
SMEMBERS key | 列出key中所有元素 |
SISMEMBER key value | 判斷key中是否存在元素value,沒(méi)找到0 |
zset
有序的set集合凿傅,通過(guò)浮點(diǎn)數(shù)score來(lái)實(shí)現(xiàn)缠犀。
元素a,b,若a.score>b.score,則a>b;若a.score=b.score,a>b,則a>b聪舒。
命令 | 說(shuō)明 |
---|---|
ZADD key score member | 向key集合中插入memeber辨液,設(shè)置score |
ZRANGE key start stop | 讀取指定范圍類(lèi)元素 |
ZRANGEBYSCORE key min man | 按照score的范圍讀取元素 |
ZREM key member | 移除元素 |
hash
包含key,value的散列表。
命令 | 說(shuō)明 |
---|---|
HMSET key field value [field value ...] | 添加值 |
HGET key field | 取值 |
HMGET key field [field ...] | 取值 |
HGETALL key | 獲取所有元素 |
HDEL key field [field ...] | 刪除指定字段 |
事務(wù)
因?yàn)閞edis是單線(xiàn)程來(lái)處理所有client的請(qǐng)求箱残,所以redis對(duì)事務(wù)的處理比較簡(jiǎn)單滔迈,通過(guò)一個(gè)類(lèi)似阻塞隊(duì)列的東西保證一個(gè)client發(fā)起的事務(wù)中的命令可以順序執(zhí)行止吁,中間不會(huì)插入其他client的命令。
通過(guò) EXEC 命令來(lái)開(kāi)啟一個(gè)事務(wù)燎悍,DISCARD取消事務(wù)敬惦,EXEC結(jié)束事務(wù)
發(fā)布訂閱
發(fā)布訂閱(pub/sub)是類(lèi)似觀(guān)察者模式的一種消息通信模式,發(fā)送者(pub)發(fā)送消息谈山,訂閱者(sub)接收消息俄删。
ps.網(wǎng)上找的圖
SUBSCRIBE 訂閱主題,開(kāi)啟通道,獲取消息
PUBLISH 推送消息
UNSUBSCRIBE 取消主題
持久化
為了防止服務(wù)宕機(jī)內(nèi)存數(shù)據(jù)丟失奏路,redis提供了三種持久化方式:RDB(deafult),AOF,RDB和AOF同時(shí)使用畴椰。
RDB:
定時(shí)調(diào)用 rdbSave 函數(shù),將內(nèi)存數(shù)據(jù)寫(xiě)入一個(gè)dump.rdb思劳,如果文件存在迅矛,替換。
操作 rdbSave 函數(shù)有兩種命令潜叛,SAVE和BGSAVE
SAVE命令會(huì)直接調(diào)用rdbSave函數(shù)秽褒,在RDB文件保存期間,主進(jìn)程會(huì)被阻塞威兜,服務(wù)端無(wú)法處理客戶(hù)端請(qǐng)求销斟,保存完成,喚醒主線(xiàn)程椒舵。
BGSAVE命令會(huì)先f(wàn)ork一個(gè)子進(jìn)程蚂踊,由子進(jìn)程調(diào)用 rdbSave 函數(shù),不會(huì)阻塞主進(jìn)程笔宿,服務(wù)端仍可服務(wù)客戶(hù)端犁钟,保存完成,子進(jìn)程會(huì)向主進(jìn)程發(fā)送通知泼橘。
在redis服務(wù)啟動(dòng)或重啟時(shí)涝动,會(huì)調(diào)用 rdbLoad 函數(shù),加載磁盤(pán)中的RDB文件到內(nèi)存中炬灭。
+-------+-------------+-----------+-----------------+-----+-----------+
| REDIS | RDB-VERSION | SELECT-DB | KEY-VALUE-PAIRS | EOF | CHECK-SUM |
+-------+-------------+-----------+-----------------+-----+-----------+
|<-------- DB-DATA ---------->|
保存策略:
save 900 10 #900s內(nèi)超過(guò)10個(gè)key被修改醋粟,發(fā)起快照保存。
AOF:
append-only-file,以協(xié)議(RESP)文本的方式重归,把數(shù)據(jù)庫(kù)的命令操作參數(shù)追加到aof文件中米愿。
這個(gè)過(guò)程分為三步:
1.命令傳播:Redis 將執(zhí)行完的命令、命令的參數(shù)鼻吮、命令的參數(shù)個(gè)數(shù)等信息發(fā)送到 AOF 程序中育苟。
2.緩存追加:AOF 程序根據(jù)接收到的命令數(shù)據(jù),將命令轉(zhuǎn)換為網(wǎng)絡(luò)通訊協(xié)議的格式椎木,然后將協(xié)議內(nèi)容追加到服務(wù)器的 AOF 緩存中宙搬。
3.文件寫(xiě)入和保存:AOF 緩存中的內(nèi)容被寫(xiě)入到 AOF 文件末尾笨腥,如果設(shè)定的 AOF 保存條件被滿(mǎn)足的話(huà), fsync 函數(shù)或者 fdatasync 函數(shù)會(huì)被調(diào)用勇垛,將寫(xiě)入的內(nèi)容真正地保存到磁盤(pán)中。
AOF支持三種保存模式:
1.AOF_FSYNC_NO :不保存士鸥。
2.AOF_FSYNC_EVERYSEC :每一秒鐘保存一次闲孤。(不阻塞主進(jìn)程)
3.AOF_FSYNC_ALWAYS :每執(zhí)行一個(gè)命令保存一次。(阻塞主進(jìn)程)
參考文獻(xiàn) -- 《Redis設(shè)計(jì)與實(shí)現(xiàn)》
可以看到 rdb文件中存儲(chǔ)的數(shù)據(jù)烤礁,aof文件中存儲(chǔ)的是命令+數(shù)據(jù)讼积,而且aof的文件可讀性更高。
除此之外脚仔,AOF的更新頻率高于RDB勤众,優(yōu)先加載aof。
復(fù)制
redis的復(fù)制方式有兩種鲤脏,一種是主(master)-從(slave)们颜,一種是從(slave)-從(slave)。
配置方式:
# 復(fù)制一份配置文件 cp redis.conf slave.conf
# 修改slave的配置 slaveof ip port
# 修改master的配置 bind 0.0.0.0
# 啟動(dòng)slave ./redis-server ../slave.conf &
集群
在redis集群中猎醇,引入了hash槽-slot的概念窥突。
集群中的節(jié)點(diǎn)node,共同分配16384個(gè)slot硫嘶,所以集群中節(jié)點(diǎn)最多只能有16384個(gè)阻问,所有的key都對(duì)映射到對(duì)應(yīng)的slot中。
redisCluster通過(guò)CRC16(key)/16384 來(lái)計(jì)算key屬于哪個(gè)槽沦疾。
通過(guò)為每個(gè)node分片不同數(shù)量的slot称近,按照槽來(lái)分片,可以控制不同節(jié)點(diǎn)的數(shù)據(jù)量和請(qǐng)求數(shù)哮塞。
redisCluster的特點(diǎn):
1.節(jié)點(diǎn)自動(dòng)發(fā)現(xiàn)
2.slave->master 選舉,集群容錯(cuò)
3.支持rehsard在線(xiàn)分片
4.節(jié)點(diǎn)直連型刨秆,不需要proxy層
5.所有節(jié)點(diǎn)彼此互連(ping-pong)
數(shù)據(jù)遷移
當(dāng)我們需要新增節(jié)點(diǎn)時(shí),只需要從以往節(jié)點(diǎn)中分配部分slot到新節(jié)點(diǎn)彻桃;需要?jiǎng)h除節(jié)點(diǎn)時(shí)坛善,先把該節(jié)點(diǎn)的slot轉(zhuǎn)移到其他節(jié)點(diǎn),然后刪除即可邻眷。這個(gè)功能極大方便了集群的線(xiàn)性擴(kuò)展或縮容眠屎,并不會(huì)造成集群不可用的狀態(tài)。
在slot遷移過(guò)程中肆饶,masterA狀態(tài)為MIGRATING改衩,masterB狀態(tài)為IMPORTING。
真正改變node映射的是鍵空間遷移驯镊。
src目錄下的集群管理命令redis-trib.rb支持reshard的手動(dòng)在線(xiàn)遷移方式葫督。
命令 | 說(shuō)明 |
---|---|
call | 在集群全部節(jié)點(diǎn)上執(zhí)行命令 |
set-timeout | 設(shè)置集群節(jié)點(diǎn)間心跳連接的超時(shí)時(shí)間 |
del-node | 從集群中刪除節(jié)點(diǎn) |
reshard | 在線(xiàn)遷移slot |
check | 檢查集群 |
import | 將外部redis數(shù)據(jù)導(dǎo)入集群 |
add-node | 將新節(jié)點(diǎn)加入集群 |
create | 創(chuàng)建集群 |
info | 查看集群信息 |
fix | 修復(fù)集群 |
rebalance | 自動(dòng)平分集群節(jié)點(diǎn)slot數(shù)量 |