成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Redis學(xué)習(xí)

miguel.jiang / 797人閱讀

摘要:?jiǎn)尉€(xiàn)程執(zhí)行命令。文件描述符事件。內(nèi)部原因不合理使用或數(shù)據(jù)結(jié)構(gòu)可能由此導(dǎo)致慢查詢(xún)等飽和是單線(xiàn)程,只會(huì)使用單個(gè)持久化阻塞操作產(chǎn)生阻塞,對(duì)硬盤(pán)的操作產(chǎn)生阻塞或?qū)懖僮髯枞?。?nèi)存達(dá)到時(shí)執(zhí)行內(nèi)存溢出控制策略。

最近在看《Redis開(kāi)發(fā)與運(yùn)維》,把自己學(xué)會(huì)的知識(shí)點(diǎn)記錄下來(lái),畢竟好記性不如爛筆頭。

一.Redis是什么。

Redis是一個(gè)Key-Value的NoSQL數(shù)據(jù)庫(kù).

二.Redis的特點(diǎn)。

1.支持的數(shù)據(jù)類(lèi)型:hash,list,set,zset,string(memacached只支持string)。

2.單線(xiàn)程執(zhí)行命令。因?yàn)槭菃尉€(xiàn)程,所以減少了線(xiàn)程上下文切換的開(kāi)銷(xiāo),同時(shí)如果一個(gè)命令執(zhí)行時(shí)間過(guò)長(zhǎng)就會(huì)引起阻塞。

3.數(shù)據(jù)持久化到內(nèi)存中,一定時(shí)間后會(huì)存儲(chǔ)到硬盤(pán)中。

三.操作數(shù)據(jù)的命令
1.常用的命令

命令 含義
keys * 查看全部的鍵,會(huì)遍歷Redis所有的鍵,時(shí)間復(fù)雜度是O(n)
scan cursor match pattern 遍歷鍵,cursor是游標(biāo)
type key 查看鍵的類(lèi)型,key是鍵的名稱(chēng)
dbsize 查看鍵的數(shù)量:dbsize 是直接獲取Redis內(nèi)置的鍵總量,時(shí)間復(fù)雜度是O(1)
exists key 判斷某個(gè)鍵是否存在,存在返回1,不存在返回0.
del key[ key...] 返回成功刪除鍵的個(gè)數(shù)
expire key time 設(shè)置鍵的過(guò)期時(shí)間
ttl key 查詢(xún)某個(gè)鍵的剩余過(guò)期時(shí)間
object encoding key 查詢(xún)鍵的內(nèi)部編碼
rename key newkey 鍵重命名
renamenx key newkey 當(dāng)newkey不存在,鍵重命名成功
randomkey 隨機(jī)選擇一個(gè)鍵
persist key 清除鍵的過(guò)期時(shí)間
move key db 在Redis內(nèi)部進(jìn)行數(shù)據(jù)庫(kù)遷移
dump + restore 在不同Redis實(shí)例間遷移數(shù)據(jù)
migrate 在數(shù)據(jù)庫(kù)實(shí)例間遷移數(shù)據(jù)

2.操作String數(shù)據(jù)類(lèi)型的命令

注意:操作String數(shù)據(jù)類(lèi)型的命令基本以s作為前綴開(kāi)頭

命令 含義
set key value 插入鍵值對(duì),key是鍵,value是值
get key 查看鍵的值
del key 刪除鍵
setnx key value 當(dāng)key不存在時(shí),設(shè)置值
setex key seconds value seconds是過(guò)期時(shí)間,設(shè)置鍵值對(duì)
mset key value[key value..] 批量獲取值
mget key [key ...] 批量獲取值
incr key 對(duì)值做自增1
decr key 對(duì)值做自減1
incrby key incrment 自增指定的數(shù)目 increment 數(shù)字
decrby key incrment 自減指定的數(shù)目 increment 數(shù)字
incrbyfloat key incrment 自增指定的浮點(diǎn)數(shù) increment 數(shù)字

內(nèi)部編碼有三種:int,embstr和raw

使用場(chǎng)景:

setnx和setex可用于分布式鎖

incr等可以用于計(jì)數(shù)

統(tǒng)一管理用戶(hù)的session

3.操作hash數(shù)據(jù)類(lèi)型的命令

注意:操作hash數(shù)據(jù)類(lèi)型的命令基本以h作為前綴開(kāi)頭

命令 含義
hset key field value 設(shè)置hash的內(nèi)容key=[{field:value}{field:value}]
hget key field 獲取字段值
hdel key field 刪除字段值
hlen key 獲取key的字段數(shù)
hmset key field value [field value...] 批量設(shè)置key的field-value
hmget key field1[field2...] 批量獲得key的field的字段值
hexists key field 判斷key的field是否存在
hkeys key 獲取key的全部字段
hvals key 獲取key的全部value值
hgetall key 獲取key的全部field,value
hincrby key field incrment key的字段field自增increment
hincrbyfloat key field increment key的字段field自增浮點(diǎn)數(shù)increment
hstrlen key field 計(jì)算field的value的長(zhǎng)度

內(nèi)部編碼:ziplist和hashtable

4.操作list數(shù)據(jù)類(lèi)型的命令

注意:操作list數(shù)據(jù)類(lèi)型的命令基本以l或r或b作為前綴開(kāi)頭

命令 含義
rpush key value[value...] 從列表右邊添加元素
lpush key value[value...] 從列表左邊添加元素
lrange key start end 獲取指定索引范圍的元素,0表示第一個(gè),-1表示最后一個(gè)
linsert key before/after pivot value 在pivot元素前/后插入value元素
lindex key index 獲取列表指定下標(biāo)的元素
llen key 獲取列表的長(zhǎng)度
lpop key 從列表的左側(cè)彈出元素
rpop key 從列表的右側(cè)彈出元素
lrem key count value 從左到右刪除count個(gè)值為value的元素
lset key index value 設(shè)置index位置的值
brpop/blpop key timeout 阻塞彈出,timeout是超時(shí)時(shí)間,0表示一直等待下去

內(nèi)部編碼:ziplist(壓縮列表),linkedlist(鏈表)和quicklist

使用場(chǎng)景:

lpush+brpop=阻塞隊(duì)列(消息隊(duì)列)。

lpush+lpop=Stack(棧)

lpush+rpop=Queue(隊(duì)列)

lpush+ltrim=Capped Collection(有限集合)

5.操作set數(shù)據(jù)類(lèi)型的命令

注意:操作set數(shù)據(jù)類(lèi)型的命令基本以s作為前綴開(kāi)頭

命令 含義
sadd key element[element...] 添加元素
srem key element[element...] 刪除元素
scard key 計(jì)算元素個(gè)數(shù)
sismember key element 判斷element元素是否在集合中
srandmember key [count] 隨機(jī)生成count個(gè)元素,默認(rèn)是1個(gè)
spop key 隨機(jī)彈出一個(gè)元素
smembers key 查詢(xún)?nèi)康脑?/td>
sinter key [key...] 查詢(xún)多個(gè)集合的并集
sunion key [key...] 查詢(xún)多個(gè)集合的交集
sdiff key [key...] 查詢(xún)多個(gè)集合的差集
sinterstore destination key [key...] 查詢(xún)多個(gè)集合的并集,存儲(chǔ)到destination中
sunionstore destination key [key...] 查詢(xún)多個(gè)集合的交集,存儲(chǔ)到destination中
sdiffstore destination key [key...] 查詢(xún)多個(gè)集合的差集,存儲(chǔ)到destination中

內(nèi)部編碼:intset,hashtable

使用場(chǎng)景:

sadd=Tagging(標(biāo)簽)

spop/srandmember=Random item(隨機(jī)數(shù)抽獎(jiǎng))

sadd+sinter=Social Graph(社交需求)

6.操作zset數(shù)據(jù)類(lèi)型的命令

注意:操作zset數(shù)據(jù)類(lèi)型的命令基本以z作為前綴開(kāi)頭

命令 含義
zadd key score memeber[score memeber...] 添加成員
zcard key 計(jì)算成員個(gè)數(shù)
zscore key member 計(jì)算成員的分?jǐn)?shù)
zrank/zrevrank key member 計(jì)算成員的排名
zrem key member[member...] 刪除成員
zincrby key increment member 增加成員的分?jǐn)?shù)
zrange/zrevrange key start end [withscores] 從低到高,返回指定排名范圍的成員
zrangebyscore key min max [withscores] [limit offset count] 從低到高,返回指定分?jǐn)?shù)范圍的成員
zrevrangebyscore key max min [withscores] [limit offset count] 返回指定分?jǐn)?shù)范圍的成員
zcount key min max 返回指定范圍的成員個(gè)數(shù)
zremrangebyrank key start end 刪除指定排名內(nèi)的升序元素
zremrangebyscore key min max 刪除指定分?jǐn)?shù)范圍的成員
zinterstore destination numberkeys key [key...] [weights weight [weight...]] [aggregate sum/min/max] 兩個(gè)有序集合的交集,numberkeys指有序集合進(jìn)行交集的個(gè)數(shù)
zunionstore destination numberkeys key [key...] [weights weight [weight...]] [aggregate sum/min/max] 兩個(gè)有序集合的并集,numberkeys指有序集合進(jìn)行并集的個(gè)數(shù)

內(nèi)部編碼:ziplist(壓縮列表)和skiplist(跳躍表)

使用場(chǎng)景:

排行榜(點(diǎn)贊)

7.Jedis對(duì)五種數(shù)據(jù)類(lèi)型的操作

Jedis jedis = null;
try {
            
    jedis = new Jedis("127.0.0.1", 6379, 10000);
            
    //1.string
    String result1 = jedis.set("string1", "value1");
    String result2 = jedis.get("string1");
    System.out.println(result1);//OK
    System.out.println(result2);//value1
            
    //2.list
    long result3 = jedis.lpush("list1", "math","math","score","score","name","xiaoming");
    List result4 = jedis.lrange("list1", 0, -1);
    System.out.println(result1);//OK
    System.out.println(result4);//xiaoming, name, score, score, math, math
            
    //3.hash
    jedis.hset("hash1", "subject","math");
    jedis.hset("hash1", "score","99");
    jedis.hset("hash1", "name","xiaoming");
    List result5 = jedis.hmget("hash1", "subject","score","name");
    System.out.println(result5);//[math, 99, xiaoming]
            
    //4.set
    jedis.sadd("set1", "math","math","english","chinese");
    jedis.sadd("set2", "math","chinese","art");
    jedis.sinterstore("set3", "set1","set2");
    System.out.println(jedis.smembers("set3"));//[math, chinese]
            
    //5.zset
    jedis.zadd("zset1", 100, "math");
    jedis.zadd("zset1", 200, "chinese");
    jedis.zadd("zset1", 300, "english");
    Set result6 = jedis.zrangeByScore("zset1", 100, 200);
    result6.forEach(string -> {
        System.out.print(string+" ");
    });//math chinese 
            
}catch(Exception e) {
    e.printStackTrace();
}finally {
    if(jedis != null) {
        jedis.close();
    }
}

四.客戶(hù)端操作

1.client list
列出與Redis服務(wù)器相連的所有客戶(hù)端信息。

屬性如下:

名稱(chēng) 含義
id 客戶(hù)端的唯一標(biāo)識(shí)。自增,重啟后重置為0。
addr 客戶(hù)端連接的地址和端口。
fd socket的文件描述符。
name 客戶(hù)端的名稱(chēng)。
age 當(dāng)前客戶(hù)端的連接時(shí)間。
idle 當(dāng)前客戶(hù)端的最近一次空閑時(shí)間。當(dāng)age等于idle表示連接一直處于空閑狀態(tài)。
flags 標(biāo)識(shí)當(dāng)前客戶(hù)端的類(lèi)型。
db 當(dāng)前客戶(hù)端正在使用的數(shù)據(jù)庫(kù)索引下標(biāo)。
sub 當(dāng)前客戶(hù)端訂閱的頻道或者模式數(shù)。
psub 當(dāng)前客戶(hù)端訂閱的頻道或者模式數(shù)。
multi 當(dāng)前事務(wù)中已執(zhí)行命令個(gè)數(shù)。
qbuf 輸入緩沖區(qū)總?cè)萘俊?/td>
qbuf-free 輸入緩沖區(qū)的剩余容量。
obl 輸出緩沖區(qū)的固定緩沖區(qū)的大小。
oll 輸出緩沖區(qū)的動(dòng)態(tài)緩沖區(qū)的大小。
omem 輸出緩沖區(qū)使用的字節(jié)數(shù)。
events 文件描述符事件。
cmd 當(dāng)前客戶(hù)端最后一次執(zhí)行的命令。

2.輸入緩沖區(qū)
作用:客戶(hù)端發(fā)送的命令不是直接發(fā)送給Redis服務(wù)器,而是先存放在輸入緩沖區(qū),Redis服務(wù)器從輸入緩沖區(qū)中獲得命令并執(zhí)行。

當(dāng)輸入緩沖區(qū)的輸入速度大于Redis服務(wù)器的處理速度且存在大量的bigkey或是Redis服務(wù)器發(fā)生阻塞,短期不能執(zhí)行命令時(shí),都會(huì)造成輸入緩沖區(qū)過(guò)大,可以通過(guò)client list查看qbuf和qbuf-free的大小或是通過(guò)info clients命令找到最大的輸入緩沖區(qū)。

3.輸出緩沖區(qū)
作用:Redis服務(wù)器執(zhí)行命令后的結(jié)果不是直接返回給客戶(hù)端,而是先存放在輸出緩沖區(qū)。

輸出緩沖區(qū)分為固定緩沖區(qū)和動(dòng)態(tài)緩沖區(qū),固定緩沖區(qū)是字節(jié)數(shù)組,動(dòng)態(tài)緩沖區(qū)是列表,固定緩沖區(qū)使用完之后才會(huì)使用動(dòng)態(tài)緩沖區(qū)。

通過(guò)client list和info clients可以監(jiān)控輸出緩沖區(qū)的異常情況。

4.客戶(hù)端的分類(lèi)
(1)普通客戶(hù)端
(2)發(fā)布訂閱客戶(hù)端
(3)slave客戶(hù)端

5.客戶(hù)端操作

命令 含義
config set maxclients value 設(shè)置最大連接數(shù)
config get maxclients 設(shè)置最大連接數(shù)
info clients 查看當(dāng)前已經(jīng)連接的客戶(hù)端數(shù)量
config set timeout value 設(shè)置超時(shí)時(shí)間,空閑時(shí)間一旦大于超時(shí)時(shí)間,客戶(hù)端連接就會(huì)自動(dòng)斷開(kāi)。
client setName value 設(shè)置客戶(hù)端的名稱(chēng)
client getName 獲得客戶(hù)端的名稱(chēng)
client kill ip:port 關(guān)閉指定的ip:port的客戶(hù)端
client pause timeout (時(shí)間單位毫秒) 阻塞客戶(hù)端timeout毫秒

五.持久化
1.RDB
(1)概念:將當(dāng)前線(xiàn)程數(shù)據(jù)生成快照保存在磁盤(pán)中。

(2)方式
a.手動(dòng)觸發(fā)
bgsave命令:Redis進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,RDB的序列化由子進(jìn)程完成,在fork階段會(huì)出現(xiàn)堵塞。

b.自動(dòng)觸發(fā)
在某些情況下自動(dòng)觸發(fā)bgsave命令或是save命令。

(3)RDB的優(yōu)缺點(diǎn)
a.優(yōu)點(diǎn)
緊湊壓縮的二進(jìn)制文件,能夠代表Redis在某個(gè)時(shí)間點(diǎn)的數(shù)據(jù)備份,可復(fù)制到不同的機(jī)器進(jìn)行災(zāi)難恢復(fù)。Redis加載RDB恢復(fù)數(shù)據(jù)的速度快于AOF。

b.缺點(diǎn)
無(wú)法實(shí)現(xiàn)實(shí)時(shí)持久化,執(zhí)行fork操作創(chuàng)建子進(jìn)程是重量級(jí)操作,頻繁執(zhí)行成本較高,且老版本的Redis服務(wù)無(wú)法兼容新版本的RDB格式文件。

2.AOF
(1)概念:記錄每次的寫(xiě)命令,重啟后執(zhí)行AOF文件中的命令以達(dá)到恢復(fù)數(shù)據(jù)的目的??梢杂胊of_enabled開(kāi)啟aof功能。

(2)特點(diǎn):
a.AOF命令以文本協(xié)議格式的形式寫(xiě)入內(nèi)容到aof_buf中,再由aof_buf同步到硬盤(pán)中。文本協(xié)議格式具有很好的兼容性以及避免了二次處理的開(kāi)銷(xiāo)。而寫(xiě)入到aof_buf中是為了避免直接寫(xiě)入硬盤(pán),以免硬盤(pán)的容量決定了追加寫(xiě)入的性能。

b.aof重寫(xiě)將無(wú)效的命令如del去掉,將多個(gè)命令合并成一個(gè)命令,以達(dá)到壓縮文件體積,加快Redis加載aof文件的速度。

六.復(fù)制
1.從節(jié)點(diǎn)和主節(jié)點(diǎn)之間建立關(guān)系有以下的方式:
(1)在配置文件(redis.conf)中加入slaveof {masterofhost} {masterofport}
(2)啟動(dòng)redis-server時(shí)執(zhí)行:redis-server -slaveof {masterofhost} {masterofport}

2.主節(jié)點(diǎn)和從節(jié)點(diǎn)斷開(kāi)和切換:
(1)斷開(kāi):slaveof no one
(2)切換:執(zhí)行命令slaveof {masterofhost} {masterofport}

3.復(fù)制的特點(diǎn)
(1)只能將主節(jié)點(diǎn)的數(shù)據(jù)復(fù)制到從節(jié)點(diǎn)。
(2)slaveof是異步命令,從節(jié)點(diǎn)保存了主節(jié)點(diǎn)的信息后返回,而不需要等到完全復(fù)制完畢才返回。
(3)可以通過(guò)命令info replication查看復(fù)制信息。
(4)從節(jié)點(diǎn)斷開(kāi)與主節(jié)點(diǎn)的復(fù)制關(guān)系后,會(huì)晉升為主節(jié)點(diǎn)。
(5)從節(jié)點(diǎn)切換主節(jié)點(diǎn)之后,會(huì)刪除從節(jié)點(diǎn)當(dāng)前的所有數(shù)據(jù),對(duì)新節(jié)點(diǎn)數(shù)據(jù)進(jìn)行復(fù)制。

4.Redis的復(fù)制關(guān)系
(1)一主一從:用于主節(jié)點(diǎn)宕機(jī)時(shí),從節(jié)點(diǎn)提供故障轉(zhuǎn)移支持。
(2)一主多從:用于讀寫(xiě)分離,主節(jié)點(diǎn)執(zhí)行寫(xiě)命令,從節(jié)點(diǎn)執(zhí)行讀命令,當(dāng)高并發(fā)寫(xiě)時(shí),將寫(xiě)命令的數(shù)據(jù)復(fù)制到從節(jié)點(diǎn)就需要消耗比較多的網(wǎng)絡(luò)帶寬。
(3)樹(shù)狀主從:從節(jié)點(diǎn)不僅可以復(fù)制主節(jié)點(diǎn)的數(shù)據(jù),還可以作為其他從節(jié)點(diǎn)的主節(jié)點(diǎn)進(jìn)行向下復(fù)制??梢杂行Ы档椭鞴?jié)點(diǎn)的負(fù)載和傳輸給從節(jié)點(diǎn)的數(shù)據(jù)量。

5.全量復(fù)制和部分復(fù)制
全量復(fù)制:將主節(jié)點(diǎn)的數(shù)據(jù)一次性發(fā)生給從節(jié)點(diǎn)。一般用于初次復(fù)制場(chǎng)景。
部分復(fù)制:僅復(fù)制主節(jié)點(diǎn)的部分?jǐn)?shù)據(jù)給從節(jié)點(diǎn)。一般用于處理主從復(fù)制中網(wǎng)絡(luò)閃斷等原因造成的數(shù)據(jù)丟失場(chǎng)景。
從節(jié)點(diǎn)執(zhí)行命令:psync {runId} {offse7dxzt}
runId是主節(jié)點(diǎn)的運(yùn)行id,offset是從節(jié)點(diǎn)已復(fù)制的偏移量。主節(jié)點(diǎn)響應(yīng)寫(xiě)命令時(shí),會(huì)把寫(xiě)命令發(fā)送給從節(jié)點(diǎn),還會(huì)將寫(xiě)命令寫(xiě)入復(fù)制積壓緩沖區(qū)。

七.Redis的阻塞
利用日志對(duì)Redis的異常進(jìn)行監(jiān)控。
內(nèi)部原因:不合理使用API或數(shù)據(jù)結(jié)構(gòu)(可能由此導(dǎo)致慢查詢(xún)等)、CPU飽和(Redis是單線(xiàn)程,只會(huì)使用單個(gè)CPU)、持久化阻塞(fork操作產(chǎn)生阻塞,AOF對(duì)硬盤(pán)的操作產(chǎn)生阻塞或HugePage寫(xiě)操作阻塞)等。
外在原因:CPU競(jìng)爭(zhēng)、內(nèi)存交換、網(wǎng)絡(luò)問(wèn)題等。

八.Redis的內(nèi)存
1.Redis進(jìn)程內(nèi)存消耗

可以通過(guò)config set maxmemory value設(shè)置最大內(nèi)存以達(dá)到伸縮內(nèi)存的目的

2.Redis內(nèi)存的回收
(1)刪除已過(guò)期的鍵對(duì)象。包括惰性刪除(查詢(xún)時(shí)判斷鍵對(duì)象是否過(guò)期,如果過(guò)期執(zhí)行刪除操作并返回空)和定時(shí)刪除。
(2)內(nèi)存達(dá)到maxmemory時(shí)執(zhí)行內(nèi)存溢出控制策略。內(nèi)存溢出策略包括noeviction,volatile-lru,allkeys-lru,allkeys-random,volatile-random和volatile-ttl,可以通過(guò)config set maxmemory-policy {policy}動(dòng)態(tài)設(shè)置。

3.內(nèi)存優(yōu)化
(1)縮短鍵和值得長(zhǎng)度,使用高效二進(jìn)制序列化工具。
(2)使用對(duì)象共享池優(yōu)化小整數(shù)對(duì)象。
(3)避免字符串的追加操作,因?yàn)樽址芳訒?huì)導(dǎo)致內(nèi)存的預(yù)分配,降低內(nèi)存的分配次數(shù)。
(4)ziplist壓縮編碼的原則是追求時(shí)間和空間的平衡,hash,zset,list的內(nèi)部編碼可以是ziplist,可以通過(guò){type}-max-ziplist-value和{type}-max-ziplist-entries進(jìn)行編碼的控制。
(5)intset是set的內(nèi)部編碼,整數(shù)集合盡量使用intset編碼,
(6)數(shù)據(jù)優(yōu)先使用整數(shù),比字符串類(lèi)型更節(jié)省內(nèi)存。

九.Redis Sentinel(哨兵)

1.Redis Sentinel是什么?
一個(gè)分布式架構(gòu),包括Sentinel節(jié)點(diǎn),Redis數(shù)據(jù)節(jié)點(diǎn)和分布在多個(gè)物理機(jī)的客戶(hù)端應(yīng)用。完成主節(jié)點(diǎn)不可用時(shí)的故障轉(zhuǎn)移處理工作,提供了高可用的解決方案。

2.Sentinel節(jié)點(diǎn)發(fā)現(xiàn)故障轉(zhuǎn)移前的內(nèi)容:
(1)每個(gè)Sentinel節(jié)點(diǎn)會(huì)對(duì)所有的數(shù)據(jù)節(jié)點(diǎn)(包括主節(jié)點(diǎn)和從節(jié)點(diǎn))和其他的Sentinel節(jié)點(diǎn)進(jìn)行監(jiān)控。
(2)當(dāng)半數(shù)以上的節(jié)點(diǎn)認(rèn)為主節(jié)點(diǎn)故障不可用,就會(huì)選擇其中一個(gè)Sentinel節(jié)點(diǎn)作為領(lǐng)導(dǎo)者進(jìn)行故障轉(zhuǎn)移處理。

3.故障轉(zhuǎn)移處理的步驟如下:
(1)對(duì)某一個(gè)從節(jié)點(diǎn)執(zhí)行slaveof no one,晉升為主節(jié)點(diǎn)。
(2)其他的從節(jié)點(diǎn)復(fù)制新的主節(jié)點(diǎn)命令(slaveof new master)。
(3)舊的主節(jié)點(diǎn)恢復(fù)后也要復(fù)制新的主節(jié)點(diǎn)命令(slaveof new master)。
(4)通知應(yīng)用方新的主節(jié)點(diǎn)。

4.為什么需要多個(gè)Rentinel節(jié)點(diǎn)?
由多個(gè)Rentinel節(jié)點(diǎn)對(duì)主節(jié)點(diǎn)不可達(dá)進(jìn)行判斷,可以防止誤判。如果有個(gè)別Rentinel節(jié)點(diǎn)失效,整個(gè)Rentinel集合依然可用。

5.Redis Sentinel的搭建
(1)建立配置文件,逐一開(kāi)啟。(配置文件的寫(xiě)法可以去看《Redis開(kāi)發(fā)與設(shè)計(jì)》第九章)
開(kāi)啟主節(jié)點(diǎn):redis-server redis-6379.conf
開(kāi)啟從節(jié)點(diǎn) redis-server redis-6380.conf

       redis-server redis-6381.conf

開(kāi)啟sentinel節(jié)點(diǎn) redis-server redis-sentinel-26379.conf --sentinel

             redis-server redis-sentinel-26380.conf --sentinel
             redis-server redis-sentinel-26381.conf --sentinel

查看主節(jié)點(diǎn)的從節(jié)點(diǎn):redis-cli -h 127.0.0.1 -p 6379 info replication
查看從節(jié)點(diǎn)的主節(jié)點(diǎn) redis-cli -h 127.0.0.1 -p 6380 info replication
查看sentinel節(jié)點(diǎn)監(jiān)控的主節(jié)點(diǎn) redis-cli -h 127.0.0.1 -p 26379 info sentinel

(2)sentinel配置文件的一些參數(shù)

參數(shù) 含義
sentinel monitor sentinel節(jié)點(diǎn)要監(jiān)控名字叫,ip地址是,端口地址是的主節(jié)點(diǎn)。表示判定主節(jié)點(diǎn)不可達(dá)需要的票數(shù)。
sentinel down-after-milliseconds sentinel節(jié)點(diǎn)會(huì)向數(shù)據(jù)節(jié)點(diǎn)和其他sentinel節(jié)點(diǎn)發(fā)送ping命令,如果節(jié)點(diǎn)在毫秒時(shí)間內(nèi)沒(méi)有回復(fù),則認(rèn)為節(jié)點(diǎn)不可達(dá)。
sentinel parallel-syncs 一次故障轉(zhuǎn)移后,每次向新節(jié)點(diǎn)發(fā)起復(fù)制操作的從節(jié)點(diǎn)個(gè)數(shù)。
sentinel failover-timeout 故障轉(zhuǎn)移的超時(shí)時(shí)間。
sentinel authpass 添加主節(jié)點(diǎn)的密碼。
sentinel notification-script 在故障轉(zhuǎn)移期間,如果發(fā)生了一些警告級(jí)別的事件(如客觀(guān)下線(xiàn),主觀(guān)下線(xiàn)等),就會(huì)觸發(fā)對(duì)應(yīng)路徑的腳本,并向腳本發(fā)送相應(yīng)的事件參數(shù)。
sentinel client-reconfig-script 在故障轉(zhuǎn)移結(jié)束后,會(huì)觸發(fā)相應(yīng)路徑下的腳本,并把故障轉(zhuǎn)移后的結(jié)果參數(shù)發(fā)送給腳本。

6.Redis Sentinel部署的特點(diǎn)
(1)將Sentinel節(jié)點(diǎn)部署在不同的物理機(jī)上,因?yàn)槿绻坏┪锢頇C(jī)出現(xiàn)故障,那這臺(tái)物理機(jī)上的Sentinel節(jié)點(diǎn)都會(huì)受到影響。
(2) 部署三個(gè)以上且奇數(shù)個(gè)Sentinel節(jié)點(diǎn),因?yàn)轭I(lǐng)導(dǎo)者選舉需要半數(shù)加上1個(gè),部署奇數(shù)個(gè)節(jié)點(diǎn)可以節(jié)省一個(gè)節(jié)點(diǎn)。
(3)如果Sentinel節(jié)點(diǎn)需要監(jiān)控同一個(gè)業(yè)務(wù)的所有主節(jié)點(diǎn)集合,就使用同一套Sentinel節(jié)點(diǎn)監(jiān)控,如果不是,就用不同的Sentinel節(jié)點(diǎn)集合監(jiān)控不同的業(yè)務(wù)的主節(jié)點(diǎn)。使用同一套Sentinel節(jié)點(diǎn)監(jiān)控可以節(jié)約資源,但是一旦出現(xiàn)異常,就會(huì)對(duì)監(jiān)控的數(shù)據(jù)節(jié)點(diǎn)造成影響。

7.Sentinel節(jié)點(diǎn)的操作(進(jìn)入某個(gè)Sentinel節(jié)點(diǎn)客戶(hù)端輸入以下操作)

操作 含義
sentinel master 查看所有的監(jiān)控的主節(jié)點(diǎn)的信息。
sentinel master 查看指定的監(jiān)控的主節(jié)點(diǎn)的信息。
sentinel get-master-addr-by-name 根據(jù)主節(jié)點(diǎn)名稱(chēng)查看主節(jié)點(diǎn)的IP地址和端口
sentinel slaves 查看主節(jié)點(diǎn)的從節(jié)點(diǎn)信息
sentinel sentinels 查看主節(jié)點(diǎn)的Sentinel節(jié)點(diǎn)信息(不包括當(dāng)前節(jié)點(diǎn))
sentinel remove 取消當(dāng)前節(jié)點(diǎn)對(duì)指定主節(jié)點(diǎn)的監(jiān)控。

8.根據(jù)Sentinel節(jié)點(diǎn)連接主節(jié)點(diǎn)

遍歷Sentinel節(jié)點(diǎn)集合獲得一個(gè)可用的Sentinel節(jié)點(diǎn),再利用sentinel get-master-addr-by-name獲得主節(jié)點(diǎn)的IP地址和端口號(hào)。

/**
 * 使用Sentinel節(jié)點(diǎn)連接主節(jié)點(diǎn)
 * @author liuffei
 * @date 2018年7月21日
 * @description
 */
public class SentinelTest {

    public static void main(String[] args) {
        
        org.slf4j.Logger logger = LoggerFactory.getLogger(SentinelTest.class);
        
        Set sentinels = new HashSet();
        sentinels.add("127.0.0.1:26379");
        sentinels.add("127.0.0.1:26380");
        sentinels.add("127.0.0.1:26381");
        JedisSentinelPool pool = new JedisSentinelPool("mymaster",sentinels);
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            String result = jedis.get("hello");
            System.out.println(result);
        }catch(Exception e) {
            logger.error(e.getMessage());
        }finally {
            if(null != jedis) {
                jedis.close();
            }
        }
    }
}

9.Sentinel的內(nèi)部原理
(1)Sentinel需要三個(gè)定時(shí)任務(wù)來(lái)保證對(duì)節(jié)點(diǎn)不可達(dá)的判斷:

每隔10秒,每個(gè)Sentinel節(jié)點(diǎn)向數(shù)據(jù)節(jié)點(diǎn)(主節(jié)點(diǎn)和從節(jié)點(diǎn))發(fā)送info replication命令獲取最新的主從關(guān)系。

每隔2秒,每個(gè)Sentinel節(jié)點(diǎn)需要向某個(gè)頻道發(fā)送自己對(duì)主節(jié)點(diǎn)是否可達(dá)的判斷和自身節(jié)點(diǎn)的信息,以發(fā)現(xiàn)新的Sentinel節(jié)點(diǎn)和Sentinel節(jié)點(diǎn)之間可以交換主節(jié)點(diǎn)的狀態(tài)。

每隔1秒,每個(gè)Sentinel節(jié)點(diǎn)需要向其它節(jié)點(diǎn)(包括主節(jié)點(diǎn),從節(jié)點(diǎn),Sentinel節(jié)點(diǎn))發(fā)送ping命令來(lái)確認(rèn)這些節(jié)點(diǎn)是否可達(dá)。

(2)主觀(guān)下線(xiàn)和客觀(guān)下線(xiàn)

主觀(guān)下線(xiàn):Sentinel節(jié)點(diǎn)向某個(gè)節(jié)點(diǎn)發(fā)出ping命令后,該節(jié)點(diǎn)在down-after-milliseconds之后沒(méi)有進(jìn)行回復(fù),Sentinel會(huì)對(duì)該節(jié)點(diǎn)做失敗判定,這個(gè)行為成為主觀(guān)下線(xiàn)。

客觀(guān)下線(xiàn):如果主觀(guān)下線(xiàn)的是主節(jié)點(diǎn),那Sentinel節(jié)點(diǎn)就會(huì)通過(guò)is-master-down-by-addr向其他Sentinel節(jié)點(diǎn)詢(xún)問(wèn)主節(jié)點(diǎn)的狀態(tài),當(dāng)Sentinel認(rèn)為主節(jié)點(diǎn)失敗的個(gè)數(shù)超過(guò)的數(shù)量,就認(rèn)為客觀(guān)下線(xiàn),需要進(jìn)行故障轉(zhuǎn)移。

(3)領(lǐng)導(dǎo)者的選舉
只需要一個(gè)Sentinel節(jié)點(diǎn)就能完成故障轉(zhuǎn)移。當(dāng)一個(gè)Sentinel節(jié)點(diǎn)完成客觀(guān)下線(xiàn)之后,會(huì)詢(xún)問(wèn)其他節(jié)點(diǎn)是否同意自己成為領(lǐng)導(dǎo)者,如果獲得票數(shù)大于等于max{quorum,num(sentinels/2+1)},就會(huì)成為領(lǐng)導(dǎo)者,

十.集群
集群和哨兵都可以保障高可用,不同的是哨兵是每臺(tái)Redis服務(wù)器存儲(chǔ)相同的數(shù)據(jù),而集群是將數(shù)據(jù)分區(qū)后,每個(gè)節(jié)點(diǎn)操作一個(gè)分區(qū)的數(shù)據(jù)。

1.數(shù)據(jù)分區(qū)
分布式數(shù)據(jù)庫(kù)需要把數(shù)據(jù)集劃分到多個(gè)節(jié)點(diǎn)上,常用的分區(qū)規(guī)則有:順序分區(qū)和哈希分區(qū)。Redis采用哈希分區(qū),哈希分區(qū)有節(jié)點(diǎn)取余分區(qū),一致性哈希分區(qū)和虛擬槽分區(qū)等等。Redis Cluster采用虛擬槽分區(qū)。

虛擬槽分區(qū):使用分散度良好的哈希函數(shù)把所有數(shù)據(jù)映射到一個(gè)固定范圍的整數(shù)集合中,整數(shù)定義為槽。槽是集群內(nèi)數(shù)據(jù)管理和遷移的基本單位。采用大范圍槽的主要目的是為了方便拆分和集群拓展。Redis Cluster采用虛擬槽分區(qū),所有的鍵根據(jù)哈希函數(shù)映射到0-16383整數(shù)槽內(nèi),計(jì)算公式:slot=CRC16(key)&16383。每個(gè)節(jié)點(diǎn)負(fù)責(zé)維護(hù)一部分槽以及槽所映射的鍵值數(shù)據(jù)。

2.集群的搭建
(1)準(zhǔn)備節(jié)點(diǎn)
需要準(zhǔn)備6臺(tái)及以上的Redis服務(wù)器才能保證完整的高可用。需要設(shè)置cluster-enabled yes。
(2)節(jié)點(diǎn)握手
概念:指一批運(yùn)行在集群模式下的節(jié)點(diǎn)通過(guò)Gossip協(xié)議通信,達(dá)到感知對(duì)方的過(guò)程。由客戶(hù)端發(fā)起命令:cluster meet {ip} {port}
(3)分配槽
只有當(dāng)節(jié)點(diǎn)分配了槽,才能響應(yīng)和這些槽關(guān)聯(lián)的鍵命令。
客戶(hù)端執(zhí)行cluster replicate {nodeId}可以讓一個(gè)節(jié)點(diǎn)變成子節(jié)點(diǎn)。

3.Gossip協(xié)議
工作原理:節(jié)點(diǎn)彼此不斷通信交換消息,一段時(shí)間后所有節(jié)點(diǎn)都會(huì)知道集群完整的信息,這種方式類(lèi)似留言傳播。
Gossip的消息包括以下:
(1)meet消息:向集群中加入新的節(jié)點(diǎn) cluster meet {ip} {port}
(2)ping消息:用于集群內(nèi)交換消息。
(3)pong消息: 響應(yīng)消息。
(4)fail消息:用于在集群內(nèi)廣播下線(xiàn)消息。

4.集群的伸縮和擴(kuò)容
(1)擴(kuò)容:準(zhǔn)備新節(jié)點(diǎn)->加入集群->分配槽和數(shù)據(jù)
(2)收縮:下線(xiàn)遷移槽->遺忘節(jié)點(diǎn)

十一.緩存
1.使用緩存的好處以及帶來(lái)的問(wèn)題
(1)好處:Redis將數(shù)據(jù)存儲(chǔ)在內(nèi)存中,可以加快寫(xiě)入和讀取的速度,同時(shí)還能在緩存層做一些復(fù)雜的操作和計(jì)算。減少了向后端的訪(fǎng)問(wèn),降低了對(duì)后端(存儲(chǔ)層)的負(fù)載。
(2)問(wèn)題:緩存層和存儲(chǔ)層的數(shù)據(jù)存在一致性問(wèn)題。增加了代碼維護(hù)和運(yùn)維成本。

2.緩存的更新策略
(1)算法剔除:當(dāng)緩存的使用量超過(guò)最大值時(shí),利用一些算法策略,刪除一部分緩存鍵值對(duì)象。
(2)過(guò)期刪除:給緩存對(duì)象設(shè)置過(guò)期時(shí)間,這會(huì)導(dǎo)致存儲(chǔ)層和緩存層的數(shù)據(jù)存在不一致,可用于實(shí)時(shí)性不高的場(chǎng)景中。
(3)主動(dòng)更新:真實(shí)數(shù)據(jù)更新后就立馬更新存儲(chǔ)層的數(shù)據(jù)??捎糜趯?shí)時(shí)性要求高的場(chǎng)景。

3.緩存全部數(shù)據(jù)和部分?jǐn)?shù)據(jù)的對(duì)比:
(1)緩存全部數(shù)據(jù)可以使用在比較多的場(chǎng)景下,但是對(duì)內(nèi)存的壓力也比較大,代碼維護(hù)壓力小。
(2)緩存部分?jǐn)?shù)據(jù)的適用場(chǎng)景比較少,對(duì)內(nèi)存壓力小,但是一旦需要在緩存中新加字段,就需要修改代碼。

4.緩存穿透
指查詢(xún)了存儲(chǔ)層和緩存層都不存在的數(shù)據(jù),存儲(chǔ)層和緩存層都不會(huì)命中。
問(wèn)題:如果不把空值存儲(chǔ)在緩存層就會(huì)導(dǎo)致頻繁訪(fǎng)問(wèn)存儲(chǔ)層,增加了數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)壓力。如果把空值存儲(chǔ)在內(nèi)存中,就會(huì)在緩存層維護(hù)一些值為空的鍵。增大了內(nèi)存的存儲(chǔ)壓力。

5.緩存“無(wú)底洞”
指添加新的節(jié)點(diǎn)機(jī)器沒(méi)有提高性能,反而導(dǎo)致性能下降。因?yàn)閷?shù)據(jù)分散存儲(chǔ)在更多的機(jī)器節(jié)點(diǎn)上了,批量操作需要從不同的節(jié)點(diǎn)上獲取。

6.緩存雪崩
指緩存層不能提供服務(wù)之后,會(huì)有大量的請(qǐng)求涌入存儲(chǔ)層,可能會(huì)導(dǎo)致存儲(chǔ)層宕機(jī)。

7.熱點(diǎn)Key失效
熱點(diǎn)Key會(huì)有大量的請(qǐng)求,短時(shí)間內(nèi)不能恢復(fù)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71682.html

相關(guān)文章

  • 【每日學(xué)習(xí)記錄】使用錄像設(shè)備記錄每天的學(xué)習(xí)

    摘要:在這里使用學(xué)而思網(wǎng)校的錄像設(shè)備,記錄每天學(xué)習(xí)的內(nèi)容閆昌李樂(lè)階段李樂(lè)李樂(lè)李樂(lè)李樂(lè)李樂(lè)李樂(lè)馬運(yùn)運(yùn)李樂(lè)李樂(lè)李樂(lè)源碼集群閆昌源碼閆昌源碼主從復(fù)制李樂(lè)源碼施洪寶源碼施洪寶韓天 在這里使用學(xué)而思網(wǎng)校的錄像設(shè)備,記錄每天學(xué)習(xí)的內(nèi)容: 2019-06-24 ~ 2019-06-28 06-27 nginx by 閆昌 06-26 nginx module by 李樂(lè) 06-25 nginx http ...

    szysky 評(píng)論0 收藏0
  • 【每日學(xué)習(xí)記錄】使用錄像設(shè)備記錄每天的學(xué)習(xí)

    摘要:在這里使用學(xué)而思網(wǎng)校的錄像設(shè)備,記錄每天學(xué)習(xí)的內(nèi)容執(zhí)行潘森執(zhí)行潘森執(zhí)行潘森趙俊峰紅黑樹(shù)景羅紅黑樹(shù)景羅配置三叉樹(shù)田志澤新建模塊馬運(yùn)運(yùn)配置田志澤田志澤田志澤李樂(lè)田志澤田志澤文件系統(tǒng) 在這里使用學(xué)而思網(wǎng)校的錄像設(shè)備,記錄每天學(xué)習(xí)的內(nèi)容: 2019-07-15 ~ 2019-07-19 07-18 nginx http 執(zhí)行 by 潘森 07-17 nginx http 執(zhí)行 by 潘森 07...

    pkhope 評(píng)論0 收藏0
  • 上古程序猿堅(jiān)決反對(duì)用Redis,我該怎么說(shuō)服他?

    摘要:前段時(shí)間,有個(gè)人吐槽自己的同事是上古程序猿,一直堅(jiān)持反對(duì)使用。上古程序猿堅(jiān)決反對(duì)用,我該怎么說(shuō)服他分布式鎖如果你是一位后端工程師,面試時(shí)八成會(huì)被問(wèn)到,特別是大廠(chǎng),不僅要求能簡(jiǎn)單使用,還要深入理解底層原理,具備解決常見(jiàn)問(wèn)題的能力。 前段時(shí)間,有個(gè)人吐槽自己的同事是上古程序猿,一直堅(jiān)持反對(duì)使用Redis。那位上古程序猿設(shè)計(jì)公司...

    番茄西紅柿 評(píng)論0 收藏2637

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<