18.分布式緩存Redis

分布式緩存

-- 基于Redis集群解決單機Redis存在的問題

單機的Redis存在四大問題:

image-20210725144240631.png

0.學習目標

1.Redis持久化

Redis有兩種持久化方案:

  • RDB持久化
  • AOF持久化

1.1.RDB持久化

RDB全稱Redis Database Backup file(Redis數據備份文件)掰读,也被叫做Redis數據快照泳挥。簡單來說就是把內存中的所有數據都記錄到磁盤中。當Redis實例故障重啟后夭委,從磁盤讀取快照文件,恢復數據。快照文件稱為RDB文件第租,默認是保存在當前運行目錄。

1.1.1.執(zhí)行時機

RDB持久化在四種情況下會執(zhí)行:

  • 執(zhí)行save命令
  • 執(zhí)行bgsave命令
  • Redis停機時
  • 觸發(fā)RDB條件時

1)save命令

執(zhí)行下面的命令我纪,可以立即執(zhí)行一次RDB:

image-20210725144536958.png

save命令會導致主進程執(zhí)行RDB,這個過程中其它所有命令都會被阻塞。只有在數據遷移時可能用到浅悉。

2)bgsave命令

下面的命令可以異步執(zhí)行RDB:

image-20210725144725943.png

這個命令執(zhí)行后會開啟獨立進程完成RDB趟据,主進程可以持續(xù)處理用戶請求,不受影響术健。

3)停機時

Redis停機時會執(zhí)行一次save命令汹碱,實現RDB持久化。

4)觸發(fā)RDB條件

Redis內部有觸發(fā)RDB的機制荞估,可以在redis.conf文件中找到咳促,格式如下:

# 900秒內,如果至少有1個key被修改勘伺,則執(zhí)行bgsave 跪腹, 如果是save "" 則表示禁用RDB
save 900 1  
save 300 10  
save 60 10000 

RDB的其它配置也可以在redis.conf文件中設置:

# 是否壓縮 ,建議不開啟,壓縮也會消耗cpu飞醉,磁盤的話不值錢
rdbcompression yes

# RDB文件名稱
dbfilename dump.rdb  

# 文件保存的路徑目錄
dir ./ 

1.1.2.RDB原理

bgsave開始時會fork主進程得到子進程冲茸,子進程共享主進程的內存數據。完成fork后讀取內存數據并寫入 RDB 文件缅帘。

fork采用的是copy-on-write技術:

  • 當主進程執(zhí)行讀操作時轴术,訪問共享內存;
  • 當主進程執(zhí)行寫操作時钦无,則會拷貝一份數據逗栽,執(zhí)行寫操作。
image-20210725151319695.png

1.1.3.小結

RDB方式bgsave的基本流程失暂?

  • fork主進程得到一個子進程彼宠,共享內存空間
  • 子進程讀取內存數據并寫入新的RDB文件
  • 用新RDB文件替換舊的RDB文件

RDB會在什么時候執(zhí)行?save 60 1000代表什么含義趣席?

  • 默認是服務停止時
  • 代表60秒內至少執(zhí)行1000次修改則觸發(fā)RDB

RDB的缺點兵志?

  • RDB執(zhí)行間隔時間長,兩次RDB之間寫入數據有丟失的風險
  • fork子進程宣肚、壓縮想罕、寫出RDB文件都比較耗時

1.2.AOF持久化

1.2.1.AOF原理

AOF全稱為Append Only File(追加文件)。Redis處理的每一個寫命令都會記錄在AOF文件霉涨,可以看做是命令日志文件按价。

image-20210725151543640.png

1.2.2.AOF配置

AOF默認是關閉的,需要修改redis.conf配置文件來開啟AOF:

# 是否開啟AOF功能笙瑟,默認是no
appendonly yes
# AOF文件的名稱
appendfilename "appendonly.aof"

AOF的命令記錄的頻率也可以通過redis.conf文件來配:

# 表示每執(zhí)行一次寫命令楼镐,立即記錄到AOF文件
appendfsync always 
# 寫命令執(zhí)行完先放入AOF緩沖區(qū),然后表示每隔1秒將緩沖區(qū)數據寫到AOF文件往枷,是默認方案
appendfsync everysec 
# 寫命令執(zhí)行完先放入AOF緩沖區(qū)框产,由操作系統(tǒng)決定何時將緩沖區(qū)內容寫回磁盤
appendfsync no

三種策略對比:

image-20210725151654046.png

1.2.3.AOF文件重寫

因為是記錄命令凄杯,AOF文件會比RDB文件大的多。而且AOF會記錄對同一個key的多次寫操作秉宿,但只有最后一次寫操作才有意義戒突。通過執(zhí)行bgrewriteaof命令,可以讓AOF文件執(zhí)行重寫功能描睦,用最少的命令達到相同效果膊存。

image-20210725151729118.png

如圖,AOF原本有三個命令忱叭,但是set num 123 和 set num 666都是對num的操作隔崎,第二次會覆蓋第一次的值,因此第一個命令記錄下來沒有意義韵丑。

所以重寫命令后爵卒,AOF文件內容就是:mset name jack num 666

Redis也會在觸發(fā)閾值時自動去重寫AOF文件。閾值也可以在redis.conf中配置:

# AOF文件比上次文件 增長超過多少百分比則觸發(fā)重寫
auto-aof-rewrite-percentage 100
# AOF文件體積最小多大以上才觸發(fā)重寫 
auto-aof-rewrite-min-size 64mb 

1.3.RDB與AOF對比

RDB和AOF各有自己的優(yōu)缺點埂息,如果對數據安全性要求較高技潘,在實際開發(fā)中往往會結合兩者來使用。

image-20210725151940515.png

2.Redis主從

2.1.搭建主從架構

單節(jié)點Redis的并發(fā)能力是有上限的千康,要進一步提高Redis的并發(fā)能力享幽,就需要搭建主從集群,實現讀寫分離拾弃。

image-20210725152037611.png

具體搭建流程參考《Redis集群》:

image-20210725152052501.png

2.2.主從數據同步原理

2.2.1.全量同步

主從第一次建立連接時值桩,會執(zhí)行全量同步,將master節(jié)點的所有數據都拷貝給slave節(jié)點豪椿,流程:

image-20210725152222497.png

這里有一個問題奔坟,master如何得知salve是第一次來連接呢?搭盾?

有幾個概念咳秉,可以作為判斷依據:

  • Replication Id:簡稱replid,是數據集的標記鸯隅,id一致則說明是同一數據集澜建。每一個master都有唯一的replid,slave則會繼承master節(jié)點的replid
  • offset:偏移量蝌以,隨著記錄在repl_baklog中的數據增多而逐漸增大炕舵。slave完成同步時也會記錄當前同步的offset。如果slave的offset小于master的offset跟畅,說明slave數據落后于master咽筋,需要更新。

因此slave做數據同步徊件,必須向master聲明自己的replication id 和offset奸攻,master才可以判斷到底需要同步哪些數據蒜危。

因為slave原本也是一個master,有自己的replid和offset舞箍,當第一次變成slave舰褪,與master建立連接時,發(fā)送的replid和offset是自己的replid和offset疏橄。

master判斷發(fā)現slave發(fā)送來的replid與自己的不一致,說明這是一個全新的slave略就,就知道要做全量同步了捎迫。

master會將自己的replid和offset都發(fā)送給這個slave,slave保存這些信息表牢。以后slave的replid就與master一致了窄绒。

因此,master判斷一個節(jié)點是否是第一次同步的依據,就是看replid是否一致

如圖:

image-20210725152700914.png

完整流程描述:

  • slave節(jié)點請求增量同步
  • master節(jié)點判斷replid儒旬,發(fā)現不一致现喳,拒絕增量同步
  • master將完整內存數據生成RDB,發(fā)送RDB到slave
  • slave清空本地數據憔涉,加載master的RDB
  • master將RDB期間的命令記錄在repl_baklog,并持續(xù)將log中的命令發(fā)送給slave
  • slave執(zhí)行接收到的命令,保持與master之間的同步

2.2.2.增量同步

全量同步需要先做RDB掏父,然后將RDB文件通過網絡傳輸個slave,成本太高了秆剪。因此除了第一次做全量同步赊淑,其它大多數時候slave與master都是做增量同步

什么是增量同步仅讽?就是只更新slave與master存在差異的部分數據陶缺。如圖:

image-20210725153201086.png

那么master怎么知道slave與自己的數據差異在哪里呢?

2.2.3.repl_backlog原理

master怎么知道slave與自己的數據差異在哪里呢?

這就要說到全量同步時的repl_baklog文件了。

這個文件是一個固定大小的數組洁灵,只不過數組是環(huán)形饱岸,也就是說角標到達數組末尾后,會再次從0開始讀寫处渣,這樣數組頭部的數據就會被覆蓋伶贰。

repl_baklog中會記錄Redis處理過的命令日志及offset,包括master當前的offset罐栈,和slave已經拷貝到的offset:

image-20210725153359022.png

slave與master的offset之間的差異黍衙,就是salve需要增量拷貝的數據了。

隨著不斷有數據寫入荠诬,master的offset逐漸變大琅翻,slave也不斷的拷貝位仁,追趕master的offset:

image-20210725153524190.png

直到數組被填滿:

image-20210725153715910.png

此時,如果有新的數據寫入方椎,就會覆蓋數組中的舊數據聂抢。不過,舊的數據只要是綠色的棠众,說明是已經被同步到slave的數據琳疏,即便被覆蓋了也沒什么影響。因為未同步的僅僅是紅色部分闸拿。

但是空盼,如果slave出現網絡阻塞,導致master的offset遠遠超過了slave的offset:

image-20210725153937031.png

如果master繼續(xù)寫入新數據新荤,其offset就會覆蓋舊的數據揽趾,直到將slave現在的offset也覆蓋:

image-20210725154155984.png

棕色框中的紅色部分,就是尚未同步苛骨,但是卻已經被覆蓋的數據篱瞎。此時如果slave恢復,需要同步痒芝,卻發(fā)現自己的offset都沒有了俐筋,無法完成增量同步了。只能做全量同步吼野。

image-20210725154216392.png

2.3.主從同步優(yōu)化

主從同步可以保證主從數據的一致性校哎,非常重要。

可以從以下幾個方面來優(yōu)化Redis主從就集群:

  • 在master中配置repl-diskless-sync yes啟用無磁盤復制瞳步,避免全量同步時的磁盤IO闷哆。
  • Redis單節(jié)點上的內存占用不要太大,減少RDB導致的過多磁盤IO
  • 適當提高repl_baklog的大小单起,發(fā)現slave宕機時盡快實現故障恢復抱怔,盡可能避免全量同步
  • 限制一個master上的slave節(jié)點數量,如果實在是太多slave嘀倒,則可以采用主-從-從鏈式結構屈留,減少master壓力

主從從架構圖:

image-20210725154405899.png

2.4.小結

簡述全量同步和增量同步區(qū)別?

  • 全量同步:master將完整內存數據生成RDB测蘑,發(fā)送RDB到slave灌危。后續(xù)命令則記錄在repl_baklog,逐個發(fā)送給slave碳胳。
  • 增量同步:slave提交自己的offset到master勇蝙,master獲取repl_baklog中從offset之后的命令給slave

什么時候執(zhí)行全量同步?

  • slave節(jié)點第一次連接master節(jié)點時
  • slave節(jié)點斷開時間太久挨约,repl_baklog中的offset已經被覆蓋時

什么時候執(zhí)行增量同步味混?

  • slave節(jié)點斷開又恢復产雹,并且在repl_baklog中能找到offset時

3.Redis哨兵

Redis提供了哨兵(Sentinel)機制來實現主從集群的自動故障恢復。

3.1.哨兵原理

3.1.1.集群結構和作用

哨兵的結構如圖:

image-20210725154528072.png

哨兵的作用如下:

  • 監(jiān)控:Sentinel 會不斷檢查您的master和slave是否按預期工作
  • 自動故障恢復:如果master故障翁锡,Sentinel會將一個slave提升為master蔓挖。當故障實例恢復后也以新的master為主
  • 通知:Sentinel充當Redis客戶端的服務發(fā)現來源,當集群發(fā)生故障轉移時馆衔,會將最新信息推送給Redis的客戶端

3.1.2.集群監(jiān)控原理

Sentinel基于心跳機制監(jiān)測服務狀態(tài)瘟判,每隔1秒向集群的每個實例發(fā)送ping命令:

?主觀下線:如果某sentinel節(jié)點發(fā)現某實例未在規(guī)定時間響應,則認為該實例主觀下線角溃。

?客觀下線:若超過指定數量(quorum)的sentinel都認為該實例主觀下線荒适,則該實例客觀下線。quorum值最好超過Sentinel實例數量的一半开镣。

image-20210725154632354.png

3.1.3.集群故障恢復原理

一旦發(fā)現master故障,sentinel需要在salve中選擇一個作為新的master咽扇,選擇依據是這樣的:

  • 首先會判斷slave節(jié)點與master節(jié)點斷開時間長短邪财,如果超過指定值(down-after-milliseconds * 10)則會排除該slave節(jié)點
  • 然后判斷slave節(jié)點的slave-priority值,越小優(yōu)先級越高质欲,如果是0則永不參與選舉
  • 如果slave-prority一樣树埠,則判斷slave節(jié)點的offset值,越大說明數據越新嘶伟,優(yōu)先級越高
  • 最后是判斷slave節(jié)點的運行id大小怎憋,越小優(yōu)先級越高。

當選出一個新的master后九昧,該如何實現切換呢绊袋?

流程如下:

  • sentinel給備選的slave1節(jié)點發(fā)送slaveof no one命令,讓該節(jié)點成為master
  • sentinel給所有其它slave發(fā)送slaveof 192.168.150.101 7002 命令铸鹰,讓這些slave成為新master的從節(jié)點癌别,開始從新的master上同步數據。
  • 最后蹋笼,sentinel將故障節(jié)點標記為slave展姐,當故障節(jié)點恢復后會自動成為新的master的slave節(jié)點
image-20210725154816841.png

3.1.4.小結

Sentinel的三個作用是什么?

  • 監(jiān)控
  • 故障轉移
  • 通知

Sentinel如何判斷一個redis實例是否健康剖毯?

  • 每隔1秒發(fā)送一次ping命令圾笨,如果超過一定時間沒有相向則認為是主觀下線
  • 如果大多數sentinel都認為實例主觀下線,則判定服務下線

故障轉移步驟有哪些逊谋?

  • 首先選定一個slave作為新的master擂达,執(zhí)行slaveof no one
  • 然后讓所有節(jié)點都執(zhí)行slaveof 新master
  • 修改故障節(jié)點配置,添加slaveof 新master

3.2.搭建哨兵集群

具體搭建流程參考課前資料《Redis集群.md》:

image-20210725155019276.png

3.3.RedisTemplate

在Sentinel集群監(jiān)管下的Redis主從集群涣狗,其節(jié)點會因為自動故障轉移而發(fā)生變化谍婉,Redis的客戶端必須感知這種變化舒憾,及時更新連接信息。Spring的RedisTemplate底層利用lettuce實現了節(jié)點的感知和自動切換穗熬。

下面镀迂,我們通過一個測試來實現RedisTemplate集成哨兵機制。

3.3.1.導入Demo工程

首先唤蔗,我們引入課前資料提供的Demo工程:

image-20210725155124958.png

3.3.2.引入依賴

在項目的pom文件中引入依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

3.3.3.配置Redis地址

然后在配置文件application.yml中指定redis的sentinel相關信息:

spring:
  redis:
    sentinel:
      master: mymaster
      nodes:
        - 192.168.150.101:27001
        - 192.168.150.101:27002
        - 192.168.150.101:27003

3.3.4.配置讀寫分離

在項目的啟動類中探遵,添加一個新的bean:

@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){
    return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}

這個bean中配置的就是讀寫策略,包括四種:

  • MASTER:從主節(jié)點讀取
  • MASTER_PREFERRED:優(yōu)先從master節(jié)點讀取妓柜,master不可用才讀取replica
  • REPLICA:從slave(replica)節(jié)點讀取
  • REPLICA _PREFERRED:優(yōu)先從slave(replica)節(jié)點讀取箱季,所有的slave都不可用才讀取master

4.Redis分片集群

4.1.搭建分片集群

主從和哨兵可以解決高可用、高并發(fā)讀的問題棍掐。但是依然有兩個問題沒有解決:

  • 海量數據存儲問題

  • 高并發(fā)寫的問題

使用分片集群可以解決上述問題藏雏,如圖:

image-20210725155747294.png

分片集群特征:

  • 集群中有多個master,每個master保存不同數據

  • 每個master都可以有多個slave節(jié)點

  • master之間通過ping監(jiān)測彼此健康狀態(tài)

  • 客戶端請求可以訪問集群任意節(jié)點作煌,最終都會被轉發(fā)到正確節(jié)點

具體搭建流程參考課前資料《Redis集群.md》:

image-20210725155806288.png

4.2.散列插槽

4.2.1.插槽原理

Redis會把每一個master節(jié)點映射到0~16383共16384個插槽(hash slot)上掘殴,查看集群信息時就能看到:

image-20210725155820320.png

數據key不是與節(jié)點綁定,而是與插槽綁定粟誓。redis會根據key的有效部分計算插槽值奏寨,分兩種情況:

  • key中包含"{}",且“{}”中至少包含1個字符鹰服,“{}”中的部分是有效部分
  • key中不包含“{}”病瞳,整個key都是有效部分

例如:key是num,那么就根據num計算悲酷,如果是{itcast}num套菜,則根據itcast計算。計算方式是利用CRC16算法得到一個hash值舔涎,然后對16384取余笼踩,得到的結果就是slot值。

image-20210725155850200.png

如圖亡嫌,在7001這個節(jié)點執(zhí)行set a 1時嚎于,對a做hash運算,對16384取余挟冠,得到的結果是15495于购,因此要存儲到103節(jié)點。

到了7003后知染,執(zhí)行get num時肋僧,對num做hash運算,對16384取余,得到的結果是2765嫌吠,因此需要切換到7001節(jié)點

4.2.1.小結

Redis如何判斷某個key應該在哪個實例止潘?

  • 將16384個插槽分配到不同的實例
  • 根據key的有效部分計算哈希值,對16384取余
  • 余數作為插槽辫诅,尋找插槽所在實例即可

如何將同一類數據固定的保存在同一個Redis實例凭戴?

  • 這一類數據使用相同的有效部分,例如key都以{typeId}為前綴

4.3.集群伸縮

redis-cli --cluster提供了很多操作集群的命令炕矮,可以通過下面方式查看:

image-20210725160138290.png

比如么夫,添加節(jié)點的命令:

image-20210725160448139.png

4.3.1.需求分析

需求:向集群中添加一個新的master節(jié)點,并向其中存儲 num = 10

  • 啟動一個新的redis實例肤视,端口為7004
  • 添加7004到之前的集群档痪,并作為一個master節(jié)點
  • 給7004節(jié)點分配插槽,使得num這個key可以存儲到7004實例

這里需要兩個新的功能:

  • 添加一個節(jié)點到集群中
  • 將部分插槽分配到新插槽

4.3.2.創(chuàng)建新的redis實例

創(chuàng)建一個文件夾:

mkdir 7004

拷貝配置文件:

cp redis.conf /7004

修改配置文件:

sed /s/6379/7004/g 7004/redis.conf

啟動

redis-server 7004/redis.conf

4.3.3.添加新節(jié)點到redis

添加節(jié)點的語法如下:

image-20210725160448139.png

執(zhí)行命令:

redis-cli --cluster add-node  192.168.150.101:7004 192.168.150.101:7001

通過命令查看集群狀態(tài):

redis-cli -p 7001 cluster nodes

如圖邢滑,7004加入了集群腐螟,并且默認是一個master節(jié)點:

image-20210725161007099.png

但是,可以看到7004節(jié)點的插槽數量為0困后,因此沒有任何數據可以存儲到7004上

4.3.4.轉移插槽

我們要將num存儲到7004節(jié)點遭垛,因此需要先看看num的插槽是多少:

image-20210725161241793.png

如上圖所示,num的插槽為2765.

我們可以將0~3000的插槽從7001轉移到7004操灿,命令格式如下:

image-20210725161401925.png

具體命令如下:

建立連接:

image-20210725161506241.png

得到下面的反饋:

image-20210725161540841.png

詢問要移動多少個插槽,我們計劃是3000個:

新的問題來了:

image-20210725161637152.png

那個node來接收這些插槽泵督?趾盐?

顯然是7004,那么7004節(jié)點的id是多少呢小腊?

image-20210725161731738.png

復制這個id救鲤,然后拷貝到剛才的控制臺后:

image-20210725161817642.png

這里詢問,你的插槽是從哪里移動過來的秩冈?

  • all:代表全部本缠,也就是三個節(jié)點各轉移一部分
  • 具體的id:目標節(jié)點的id
  • done:沒有了

這里我們要從7001獲取,因此填寫7001的id:

image-20210725162030478.png

填完后入问,點擊done丹锹,這樣插槽轉移就準備好了:

image-20210725162101228.png

確認要轉移嗎?輸入yes:

然后芬失,通過命令查看結果:

image-20210725162145497.png

可以看到:

image-20210725162224058.png

目的達成楣黍。

4.4.故障轉移

集群初識狀態(tài)是這樣的:

image-20210727161152065.png

其中7001、7002棱烂、7003都是master租漂,我們計劃讓7002宕機。

4.4.1.自動故障轉移

當集群中有一個master宕機會發(fā)生什么呢?

直接停止一個redis實例哩治,例如7002:

redis-cli -p 7002 shutdown

1)首先是該實例與其它實例失去連接

2)然后是疑似宕機:

image-20210725162319490.png

3)最后是確定下線秃踩,自動提升一個slave為新的master:

image-20210725162408979.png

4)當7002再次啟動,就會變?yōu)橐粋€slave節(jié)點了:

image-20210727160803386.png

4.4.2.手動故障轉移

利用cluster failover命令可以手動讓集群中的某個master宕機业筏,切換到執(zhí)行cluster failover命令的這個slave節(jié)點憔杨,實現無感知的數據遷移。其流程如下:

image-20210725162441407.png

這種failover命令可以指定三種模式:

  • 缺始菘住:默認的流程芍秆,如圖1~6歩
  • force:省略了對offset的一致性校驗
  • takeover:直接執(zhí)行第5歩,忽略數據一致性翠勉、忽略master狀態(tài)和其它master的意見

案例需求:在7002這個slave節(jié)點執(zhí)行手動故障轉移妖啥,重新奪回master地位

步驟如下:

1)利用redis-cli連接7002這個節(jié)點

2)執(zhí)行cluster failover命令

如圖:

image-20210727160037766.png

效果:

image-20210727161152065.png

4.5.RedisTemplate訪問分片集群

RedisTemplate底層同樣基于lettuce實現了分片集群的支持,而使用的步驟與哨兵模式基本一致:

1)引入redis的starter依賴

2)配置分片集群地址

3)配置讀寫分離

與哨兵模式相比对碌,其中只有分片集群的配置方式略有差異荆虱,如下:

spring:
  redis:
    cluster:
      nodes:
        - 192.168.150.101:7001
        - 192.168.150.101:7002
        - 192.168.150.101:7003
        - 192.168.150.101:8001
        - 192.168.150.101:8002
        - 192.168.150.101:8003
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市朽们,隨后出現的幾起案子怀读,更是在濱河造成了極大的恐慌,老刑警劉巖骑脱,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菜枷,死亡現場離奇詭異,居然都是意外死亡叁丧,警方通過查閱死者的電腦和手機啤誊,發(fā)現死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拥娄,“玉大人蚊锹,你說我怎么就攤上這事≈神” “怎么了牡昆?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摊欠。 經常有香客問我丢烘,道長,這世上最難降的妖魔是什么些椒? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任铅协,我火速辦了婚禮,結果婚禮上摊沉,老公的妹妹穿的比我還像新娘狐史。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布骏全。 她就那樣靜靜地躺著苍柏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪姜贡。 梳的紋絲不亂的頭發(fā)上试吁,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音楼咳,去河邊找鬼熄捍。 笑死,一個胖子當著我的面吹牛母怜,可吹牛的內容都是我干的余耽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼苹熏,長吁一口氣:“原來是場噩夢啊……” “哼碟贾!你這毒婦竟也來了?” 一聲冷哼從身側響起轨域,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤袱耽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后干发,有當地人在樹林里發(fā)現了一具尸體朱巨,經...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年枉长,在試婚紗的時候發(fā)現自己被綠了蔬崩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡搀暑,死狀恐怖,靈堂內的尸體忽然破棺而出跨琳,到底是詐尸還是另有隱情自点,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布脉让,位于F島的核電站桂敛,受9級特大地震影響,放射性物質發(fā)生泄漏溅潜。R本人自食惡果不足惜术唬,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望滚澜。 院中可真熱鬧粗仓,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蚂斤,卻和暖如春存捺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背曙蒸。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工捌治, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纽窟。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓肖油,卻偏偏與公主長得像,于是被迫代替她去往敵國和親师倔。 傳聞我的和親對象是個殘疾皇子构韵,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容

  • 零、本文綱要 一趋艘、單機Redis的問題二疲恢、Redis持久化(一)RDB持久化(二)AOF持久化(三)RDB與AOF...
    石頭耳東閱讀 670評論 0 3
  • 1 在項目中緩存是如何使用的?緩存如果使用不當會造成什么后果瓷胧? 這個問題幾乎是互聯網公司必問的显拳,是基礎中的基礎。 ...
    Teemo_fca4閱讀 232評論 0 0
  • 單線程模型網絡IO和鍵值對讀寫是單線程持久化搓萧,異步刪除杂数,數據同步是額外線程執(zhí)行。 為什么單線程模型這么快瘸洛?內存操作...
    程序員札記閱讀 195評論 0 1
  • 1反肋、緩存定義 高速數據存儲層那伐,提高程序性能 2、為什么要用緩存(讀多寫少石蔗,高并發(fā)) 1罕邀、提高讀取吞吐量 2、提升應...
    一只程序猿喲閱讀 266評論 0 0
  • 在前面文章介紹了Redis的一些常用命令养距,及持久化方式诉探,那么Redis作為一個分布式緩存是怎么保證自己數據的高可用...
    木子蔥蔥閱讀 197評論 0 0