做網(wǎng)站 搞流量 賺廣告費(fèi)seo網(wǎng)站優(yōu)化軟件價格
線程模型
純內(nèi)存操作/非阻塞io多路復(fù)用/單線程避免多線程頻繁上下文切換
? ? ?基于Reactor模式開發(fā)了網(wǎng)絡(luò)事件處理器:文件事件處理器,單線程的 io多路監(jiān)聽多個socket,據(jù)socket事件類型選擇對應(yīng)的處理器,高性能網(wǎng)絡(luò)通信模型,可其他單線程對接 簡單性
? ? 文件事件處理器:多個socket? io多路復(fù)用? 文件事件分派器? 事件處理器
? ? io多路復(fù)用監(jiān)聽多個socket,將socket放入隊(duì)列排隊(duì),每次從隊(duì)列中取出socket給事件分派器,給對應(yīng)事件處理器,處理完,io多路復(fù)用將隊(duì)列下一個socket給事件分派器
reactor
?synchronous event demultiplexer:同步事件分離器,監(jiān)聽各種事件,調(diào)用方調(diào)用監(jiān)聽方法的時候會被阻塞 直到有事件發(fā)生
handler:文件描述符,簡單理解一個一個事件?
event handler:事件處理器,回調(diào)方法,事件發(fā)生 據(jù)handler調(diào)用對應(yīng)的回調(diào)方法? 自己實(shí)現(xiàn)方法
步驟:
高可用:
? 主從
? ? 哨兵:sentinel: 集群監(jiān)控 消息通知 故障轉(zhuǎn)移 配置中心
redis cluster :livu livechat中使用了
?人家有槽slot 16384個呢?請求發(fā)送任意節(jié)點(diǎn) 該節(jié)點(diǎn)會將請求發(fā)送到正確節(jié)點(diǎn)上-相親相愛
? ? 1.哈希的方式,將數(shù)據(jù)分片 每個節(jié)點(diǎn)均分存儲一定哈希槽區(qū)間的數(shù)據(jù)
? ? 2.每份數(shù)據(jù)分片會存儲在多個互為主從的多節(jié)點(diǎn)上
? ? 3.先寫主節(jié)點(diǎn)再同步從節(jié)點(diǎn)
? ? 4.讀取數(shù)據(jù),當(dāng)客戶端操作的key沒有分配在該節(jié)點(diǎn),返回轉(zhuǎn)向指令,指向正確節(jié)點(diǎn)
? ? 5.擴(kuò)容時需要把舊節(jié)點(diǎn)的數(shù)據(jù)遷移一部分到新節(jié)點(diǎn)
? ? 6.每個redis放開兩個端口,6379 16379,16379節(jié)點(diǎn)間通信,cluster bus,故障檢測/轉(zhuǎn)移
? ? 7.cluster bus用gossip二進(jìn)制協(xié)議,節(jié)點(diǎn)間高效數(shù)據(jù)交換,占用更少的網(wǎng)絡(luò)帶寬和處理時間
優(yōu)缺點(diǎn):誰還能沒點(diǎn)缺
無中心架構(gòu),支持動態(tài)擴(kuò)容,對業(yè)務(wù)透明
自備sentinel監(jiān)控和自動failover故障轉(zhuǎn)移能力
高性能,直連redis服務(wù) 免去proxy損耗
有點(diǎn)缺:人無完人 redis無完美? 怎么說:反正有缺點(diǎn)但是值得
? ? 運(yùn)維復(fù)雜 數(shù)據(jù)遷移需要人工 只能使用0號數(shù)據(jù)庫 不支持批量操作 分布式邏輯和存儲模塊耦合
redis sharding:你可以不看? 讓我自己卷
多redis實(shí)例集群,采用哈希算法將redis的key進(jìn)行散列,映射到特定的redis節(jié)點(diǎn)
? ?簡單,服務(wù)端redis實(shí)例彼此獨(dú)立,相互無關(guān)聯(lián),每個redis實(shí)例像單服務(wù)器一樣 線性擴(kuò)展
? ?不支持動態(tài)刪增節(jié)點(diǎn),服務(wù)器redis實(shí)例群拓?fù)浣Y(jié)構(gòu)變化,每個客戶更新調(diào)整 連接不共享?
三大熱門問題:
還行 咱家項(xiàng)目設(shè)計穩(wěn)穩(wěn)當(dāng)當(dāng) 上學(xué)的時候遇到過一次
緩存穿透:緩存 數(shù)據(jù)庫都沒有的數(shù)據(jù),庫短時間內(nèi)承受大量請求
? ? 接口層校驗(yàn),緩存取不到庫中也沒有,可key-null 短的過期時間,布隆過濾器bitmap中
緩存擊穿:緩存中沒有庫中有,并發(fā)查同一條數(shù)據(jù)
? ? 熱點(diǎn)永不過期,互斥鎖
緩存雪崩:一瞬間大面積失效
? ? 設(shè)置隨機(jī)過期時間/新增緩存標(biāo)記是否失效/緩存預(yù)熱/互斥鎖
一致性:
寫不太頻繁:
1,操作緩存 設(shè)置過期標(biāo)識 客戶端讀緩存過期則休眠再查redis
2,先刪緩存,看他不順眼直接刪了!再寫數(shù)據(jù)庫,休眠 再刪緩存
主從同步
1 從節(jié)點(diǎn)slaveof masterip port 保存主節(jié)點(diǎn)信息
2 從節(jié)點(diǎn)定時任務(wù)發(fā)現(xiàn)主節(jié)點(diǎn),建立和主節(jié)點(diǎn)socket連接
3 從發(fā)送信號 主返回 互相私通 呸 互相私信,連接建立 主all數(shù)據(jù)發(fā)送給從
runid:每個redis節(jié)點(diǎn)啟動生成唯一標(biāo)識uuid
offset:主從各自維護(hù)自己的復(fù)制偏移量,主也寫offset=offset+命令字節(jié)長度,從收到主發(fā)送命令后,增加自己的offset,把自己的offset發(fā)送給主節(jié)點(diǎn),主節(jié)點(diǎn)同時保存自己的offset和從的,對比判斷主從一致性數(shù)據(jù)
原理
?
repl_backlog_size:主節(jié)點(diǎn)上固定長度的先進(jìn)先出隊(duì)列1M
復(fù)制
全量復(fù)制:主節(jié)點(diǎn)bgsave命令fork子進(jìn)程 rdb,消耗cpu 內(nèi)存 硬盤id,主節(jié)點(diǎn)通網(wǎng)絡(luò)rdb給從,從清空老數(shù)據(jù) 載入rdb(阻塞)?
部分復(fù)制:執(zhí)行復(fù)制的雙方,分別維護(hù)offset,主內(nèi)部維護(hù)固長 fifo復(fù)制積壓緩存區(qū)隊(duì)列,主offset差距大過緩存區(qū)長度,全量復(fù)制;服務(wù)器runid 主把自己的runid發(fā)送給從 從存 從重連時 據(jù)runid判斷同步進(jìn)度
? ?runid同之前同步過 主嘗試部分復(fù)制 ;不同全量復(fù)制
事務(wù)ACISD
單線程? watch監(jiān)控key的情況
1,multi命令的執(zhí)行(事務(wù)的開始),multi將客戶端狀態(tài)的flags=redis_multi
2,命令multi/exec/watch/discard會立即執(zhí)行,否則將命令放入事務(wù)隊(duì)列 客戶端返回queue
? 其他命令 先檢查格式 如果說來搗亂 服務(wù)器把客戶端狀態(tài)flags關(guān)閉redis_multi 返回錯誤 小黑屋了
? ?隊(duì)列說FIFO 先進(jìn)先出講規(guī)矩的隊(duì)列
3,執(zhí)行:
不支持回滾;
watch樂觀鎖為redis提供check-and-set(cas)監(jiān)控多個鍵,有一個被修改則后面的事務(wù)不執(zhí)行 監(jiān)控持續(xù)到exec命令
multi開啟事務(wù),執(zhí)行后客戶端可持續(xù)向服務(wù)器發(fā)送任意多條命令,放入隊(duì)列 exec被調(diào) all命令執(zhí)行
exec 執(zhí)行事務(wù)塊內(nèi)命令,按命令執(zhí)行先后順序排列,操作被打斷 返回空值null
調(diào)用discard客戶端可清空事務(wù)隊(duì)列,放棄執(zhí)行事務(wù)
unwatch取消watch對所有key對監(jiān)控
分布式鎖
setnx+setex 設(shè)置超時時間失敗,死鎖
set(key,value,px)原子操作
? redisson解決任務(wù)超時 鎖自動釋放 并發(fā)問題
數(shù)據(jù)結(jié)構(gòu)
string
list
hash
set
sortedSet
bitmap
geohash:sortedSet?
hyperLogLog??
streams
緩存過期策略
定期過期:定時器清理 占大量CPU處理過期數(shù)據(jù) 緩存響應(yīng)時間和吞吐量
惰性過期:先判斷是否過期,過期刪除,節(jié)省CPU資源 消耗內(nèi)存?
定期過期:每隔一段時間,掃描一定數(shù)量的數(shù)據(jù)庫中expires字典中一定數(shù)量的key
淘汰算法
fifo:被存儲時間 最遠(yuǎn)的先淘汰
LRU:最近最少使用,最近被使用的時間
LFU:最不經(jīng)常使用,一段時間內(nèi) 緩存被使用次數(shù)最少
緩存方案:
客戶端緩存:頁面 瀏覽器緩存 app h5 localStorage sessionStorage
CND緩存:內(nèi)容存儲? 數(shù)據(jù)緩存? 內(nèi)容分發(fā) 負(fù)載均衡
nginx緩存:靜態(tài)資源
服務(wù)端緩存:本地緩存 外部緩存
數(shù)據(jù)庫緩存:持久層緩存 mybatis。hibernate多級緩存 mysql查詢
操作系統(tǒng)緩存:page cache。 buffer? cache
redis集群策略
主從:主可寫讀,和從數(shù)據(jù)同步,主從宕 客戶端手動修改ip?
哨兵模式:主庫宕 哨兵從 從庫選主 哨兵也可以集群 高可用 容量上的限制
cluster:多主多從 按key進(jìn)行槽位分配 不同key分散不同主節(jié)點(diǎn)上?
持久化
save命令,redis阻塞 直到rdb完成
bgsave,fork子進(jìn)程 主進(jìn)程在fork過程中短暫阻塞,子進(jìn)程創(chuàng)建完主進(jìn)程響應(yīng)客戶端請求
save m n:m秒內(nèi)n隔鍵改變 自動觸發(fā)持久化 bgsave進(jìn)行 設(shè)置多個滿足其一就觸發(fā)
flushall:清空redis所有數(shù)據(jù),flushdb清空當(dāng)前redis所在庫數(shù)據(jù)(0號庫 rdb文件)
主動同步:全量同步自動觸發(fā)bgsave命令
?一個dump.rdb文件,方便持久化 容災(zāi)性好 方便備份 性能最大化 fork子進(jìn)程完成寫操作?
數(shù)據(jù)安全性低,rdb間隔一段時間進(jìn)行持久化,redis故障,數(shù)據(jù)丟失?
aof:親這邊建議優(yōu)先使用
? 日志形式記錄服務(wù)器處理的每一個寫 刪除操作
? ?aof緩存區(qū)據(jù)策略向硬盤同步操作,定期對aof文件重寫 壓縮的目的
? ?每秒同步:異步完成 效率高,一秒數(shù)據(jù)會被丟失宕機(jī)時
? ?每修改同步:同步持久化,每次發(fā)生數(shù)據(jù)變化 立即記錄到磁盤 最多丟一條
? ?不同步:操作系統(tǒng)控制 丟失更多數(shù)據(jù)
數(shù)據(jù)安全,redis-check-aof工具解決數(shù)據(jù)一致性問題
aof文件大 恢復(fù)慢 ;數(shù)據(jù)集大 rdb啟動效率低,運(yùn)行效率無rdb高