Redis

NOsql

泛指非關(guān)系型數(shù)據(jù)庫啊研,為了克服超大規(guī)模的高并發(fā)的問題畏腕,NoSQL在當(dāng)今大數(shù)據(jù)環(huán)境下發(fā)展的十分迅速凸主,Redis是發(fā)展最快的橘券。

方便擴展(數(shù)據(jù)之間沒有關(guān)系)

大數(shù)據(jù)量高性能(Redis一秒寫8萬次,讀取11萬次卿吐,NoSQL的緩存記錄級旁舰,是一種細(xì)粒度的緩存,性能會比較高)

數(shù)據(jù)類型是多樣的(不需要事先設(shè)計數(shù)據(jù)庫)

發(fā)展歷程

單機MySQL->緩存+Mysql+垂直拆分(讀寫分離)->分庫分表+水平拆分+服務(wù)器集群

四大分類

K-V鍵值對 -Redis

文檔型數(shù)據(jù)庫

MongoDB是一個基于分布式文件存儲的數(shù)據(jù)庫嗡官,C++編寫箭窜,主要用來處理大量的文檔!

MongoDB是一個介于關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫中間的產(chǎn)品

MongoDB是非關(guān)系型數(shù)據(jù)庫中功能最豐富的

列存儲數(shù)據(jù)庫 -HBase? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -分布式文件系統(tǒng)

圖關(guān)系數(shù)據(jù)庫 -Neo4J? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -InfoGird

Redis入門

簡介:一個開源的使用ANSI C語言編寫衍腥,支持網(wǎng)絡(luò)磺樱,可基于內(nèi)存衣可持久化的日志型,K-V數(shù)據(jù)庫婆咸,并提供多種語言的API竹捉。免費和開源!

windows安裝

下載安裝包

通過CMD啟動尚骄,cd到redis的安裝目錄下

運行命令 redis-server redis.windows.conf

Linux安裝

下載安裝包块差,放到/opt目錄下 ,解壓

進入解壓后的文件,找到redis.conf

yum install gcc-c++ ? ?

make ? //下載環(huán)境

make install

redis的默認(rèn)安裝路徑? /usr/local/bin

復(fù)制配置文件到指定目錄

redis配置文件復(fù)制

redis默認(rèn)不是后臺啟動的憾儒,修改配置文件询兴,使redis后臺啟動

后臺啟動

啟動redis服務(wù)

啟動及測試

查看redis進程是否開啟

Redis性能測試

redis -benchmark

redis性能測試參數(shù)

Redis基礎(chǔ)

redis有16個數(shù)據(jù)庫乃沙,默認(rèn)使用第0個起趾。

Redis是單線程的,基于內(nèi)存操作警儒,CPU不是Redis的性能瓶頸训裆,Redis的瓶頸是根據(jù)機器的內(nèi)存和網(wǎng)絡(luò)帶寬,既然可以使用單線程來實現(xiàn)蜀铲,就使用單線程來實現(xiàn)

Redis是C語言寫的边琉,每秒100000+的QPS,完全不比同樣是使用key-value的Memecache(一套分布式的快取系統(tǒng))差.

Redis為什么單線程還這么快?

誤區(qū)1:高性能的服務(wù)器一定是多線程的记劝?

誤區(qū)2:多線程(CPU上下文會切換)一定比單線程效率高变姨!

核心:redis將所有的數(shù)據(jù)全部放在內(nèi)存中,所以使用單線程去操作效率最高厌丑,多線程(CPU上下文會切換:耗時的操作)定欧,對于內(nèi)存系統(tǒng)來說,如果沒有上下文切換效率就是最高的怒竿!多次讀寫都是在一個CPU上的砍鸠,這就是最佳方案。

五大數(shù)據(jù)類型

Redis-Key

setkey value#set key

keys *#查看所有key

exists key#判斷當(dāng)前key是否存在

move key database#移除當(dāng)前key

expire key seconds#設(shè)置key的過期時間耕驰,單位秒

tll key#查看當(dāng)前key的剩余時間

type key#查看當(dāng)前key的類型

append key “”#追加/如key不存在就相當(dāng)于set

strlen key#獲取字符創(chuàng)的長度

################################################

#步長 i+=

#i++

setviews0#初始瀏覽量為0

incr views#自增1

decr views#自減1

incrby views10#可以設(shè)置步長爷辱,指定增量

###################################################

#字符串范圍? range

GETRANGE key03#截取字符串[0,3]

GETRANGE key0-1#獲取全部的字符串

#替換

SETRANGE key1xx#替換指定位置開始的字符串

#######################################################

#setex (set with expire) #設(shè)置過期時間

#setnx (set if not exist) #不存在 再設(shè)置 (在分布式鎖種會常常使用!)

############################################################

mset#同時設(shè)置多個值

mget#同時獲取多個值

#對象

setuser:1 {name:wir,age:3}#設(shè)置一個user:1對象值為json字符來保存一個對象

#######################################################################

getset#先get再set

#如果不存在值朦肘,怎創(chuàng)建返回nil饭弓;如果存在值,獲取原來的值并設(shè)置新值

String

String類似的使用場景:value除了是字符串還可以是數(shù)字

計數(shù)器

統(tǒng)計多單位的數(shù)量

List(命令l開頭)

基本的數(shù)據(jù)類型媒抠,列表弟断;可以用list實現(xiàn)棧,隊列领舰,阻塞隊列夫嗓。

LPUSH list one#將一個值(多個),插入到列表的頭部(左)

RPUSH list right#將一個值(多個)冲秽,插入到列表的頭部(右)

LRANGE list0-1#查詢list

#####################################################

LPOP

RPOP

LPOP list#移除list的第一個元素

RPOP list#移除list的最后一個元素

#########################################################

Llen? list#返回list的長度

###############################

lrem list1one#移除 list集合中指定個數(shù)的value

ltrim list12#通過下標(biāo)截取指定的長度

##################################################

rpoplpush#移除列表的最后一個元素舍咖,將它移動到新的列表中!

rpoplpush list1 list2

###################################################

小結(jié)

list實際上類似鏈表锉桑,left排霉,right,before Node after 都可以插入值

如果key不存在民轴,創(chuàng)建新的鏈表

如果key存在攻柠,新增內(nèi)容

如果移除了所有值球订,鏈表空,表示不存在

在兩邊插入或者改動值效率最高瑰钮!中間元素冒滩,相對來說效率會低一點~

消息排隊!消息隊列(Lpush Rpop),棧(Lpush Lpop)

Set(集合)

##########################################################

sadd myset"hello"#set集合紅添加元素

SMEMBERS myser#查看指定set的所有值

SISMEMBER myset hello#判斷某一個值在集合中是否存在

########################################

srem myset hello#移除set集合中的指定元素

########################################

SRANDMEMBER myset /2#隨機拿出一個元素 /指定個數(shù)的元素

#################################

spop myset#隨機刪除key中的元素

#########################

smove key1 key2"xxx"#將xxx移動到key2 中

##############################

SDIFF k1 k2#查看k1 k2兩個集合中不同的元素

SINTER k1 k2#查看k1 k2兩個集合中相同的元素

SUNION k1 k2#查看k1 k2兩個集合中所有元素

Hash(哈希)

key -<key,value>(map)!這個value是一個map集合 浪谴;可以做變更數(shù)據(jù)开睡,例如用戶信息

##############################################

hset key field1 value#set一個具體的 key-value

hmset key field1 value11 field2 value22#同時set多個具體的k-v

hmget key field1 field2#獲取多個字段

hgetall key#獲取全部數(shù)據(jù)

######################################################

hdel key field1#刪除hash指定的key

#####################################################

hlen key#獲取hash表的字段數(shù)量

#####################################

HEXISTS key field1#判斷hash中指定字段是否存在

############################################

hkeys key#獲取所有的key

hvalues key#獲取所有的value

Zset(有序集合)

三種特殊數(shù)據(jù)類型

Geospatial-地理空間

#geoadd

#規(guī)則:兩極無法直接添加,一般通過程序一次性導(dǎo)入

#參數(shù) key 值(緯度苟耻,經(jīng)度篇恒,名稱)

geoadd china:city116.40.39.90 beijing#添加坐標(biāo)

#geopos

geopos china:city beijing#獲取指定的城市的經(jīng)度和緯度

#geodist

geodist china:china beijin shanghai km# 兩地距離? 單位:m,km,mi(英里),ft(英尺)

#georadius

georadius china:city110301000km withdist withcoord count1#以經(jīng)緯度為中心1000km為半徑查找 顯示到中間距離的位置 顯示他人的定位信息 篩選出指定的結(jié)果

#georadiusbymember

georadiusbymember china:city beijing1000km#找出位于指定元素周圍的其他元素

Hyperloglog

占用的內(nèi)存是固定的凶杖,2^64不同的元素基數(shù)胁艰,只要12KB內(nèi)存。0.18%錯誤率智蝠!

PFadd key

PFCOUNT key#統(tǒng)計

Bitmaps-位存儲

bitmaps位圖腾么,數(shù)據(jù)結(jié)構(gòu)!都是操作二進制位來進行記錄寻咒,就只有0和1兩個狀態(tài)哮翘!

事務(wù)

Redis事務(wù)本質(zhì):一組命令的集合!一個事務(wù)中的所有命令都會被序列化毛秘,在事務(wù)執(zhí)行過程中饭寺,會按照順序執(zhí)行!

一次性叫挟,順序性艰匙,排他性!執(zhí)行一些列的命令抹恳!

Redis事務(wù)沒有隔離級別的概念员凝!(不會出現(xiàn)臟讀,幻讀奋献,不可重復(fù)讀)

所有的命令在事務(wù)中健霹,并沒有直接被執(zhí)行!只有發(fā)起執(zhí)行命令的時候才會執(zhí)行瓶蚂!Exec

Redis單條命令是保證原子性的糖埋,但是事務(wù)不保證原子性

redis事務(wù)

開啟事務(wù)(multi)

命令入隊()

執(zhí)行事務(wù)(exec)

正常執(zhí)行事務(wù)

redis事務(wù)

放棄事務(wù)-discard#取消事務(wù)

編譯型異常(代碼有問題!命令有錯)窃这,事務(wù)中所有的命令都不會被執(zhí)行

運行時異常瞳别,如果事務(wù)隊列中存在語法錯誤,那么執(zhí)行命令的時候,其他命令是可以正常執(zhí)行的祟敛,錯誤命令會拋出異常

監(jiān)控! Watch

悲觀鎖:

悲觀疤坝,無論做什么都加鎖!效率低下

樂觀鎖:

樂觀,認(rèn)為不會出問題馆铁,所以不加鎖跑揉!更新數(shù)據(jù)時去判斷在此期間是否有人修改數(shù)據(jù)。

獲取version

更新時比較version

Redis監(jiān)控測試

正常執(zhí)行成功叼架!

127.0.0.1:6379> set money 100

OK

127.0.0.1:6379> set out 0

OK

127.0.0.1:6379> watch money #監(jiān)視money對象

OK

127.0.0.1:6379> multi #事務(wù)正常結(jié)束畔裕,數(shù)據(jù)期間沒有發(fā)生變動,這個時候就正常執(zhí)行成功

OK

127.0.0.1:6379(TX)> DECRBY money 20

QUEUED

127.0.0.1:6379(TX)> INCRBY out 20

QUEUED

127.0.0.1:6379(TX)> exec

1) (integer) 80

2) (integer) 20

如果事務(wù)執(zhí)行失敼远!就先unwatch(解除監(jiān)視)然后再watch(再次監(jiān)視)具练,最后對比監(jiān)視的值是否發(fā)生變化乍构,如果沒有變化,那么可以成功扛点,如果有變化就執(zhí)行失敻缯凇!繼續(xù)重復(fù)陵究。

Jedis

Jedis是Redis官方推薦的Java連接開發(fā)工具眠饮!使用Java操作Redis中間件

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>3.5.1</version>

</dependency>

具體方法同redis命令

Spring Boot整合

SpringBoot2.x之后,原來使用的jedis被替換為lettuce

jedis:才用的直連铜邮,多個線程操作的話仪召,是不安全的,如果想要避免不安全松蒜,需要使用jedis pool 連接池扔茅!

lettuce :采用netty,實例可以在多個線程中進行共享秸苗,可以減少線程數(shù)量

源碼分析:

@Bean

@ConditionalOnMissingBean(name="redisTemplate")//如果沒有配置Bean會生效召娜,所以可以自己定義一個redisTemplate來替換

@ConditionalOnSingleCandidate(RedisConnectionFactory.class)

publicRedisTemplate<Object,Object>redisTemplate(RedisConnectionFactoryredisConnectionFactory) {

//默認(rèn)的RedisTemplate沒有過多的設(shè)置,redis對象都是需要序列化的

//泛型都是object惊楼,類型玖瘸,使用后需要強制類型轉(zhuǎn)換

RedisTemplate<Object,Object>template=newRedisTemplate<>();

template.setConnectionFactory(redisConnectionFactory);

returntemplate;

}

@Bean

@ConditionalOnMissingBean

@ConditionalOnSingleCandidate(RedisConnectionFactory.class)//String是redis中最常使用的類型,所以單獨提出來一個bean

publicStringRedisTemplatestringRedisTemplate(RedisConnectionFactoryredisConnectionFactory) {

StringRedisTemplatetemplate=newStringRedisTemplate();

template.setConnectionFactory(redisConnectionFactory);

returntemplate;

}

Redis持久化

Redis是基于內(nèi)存的數(shù)據(jù)庫檀咙,如果不將內(nèi)存中的數(shù)據(jù)保存到磁盤雅倒,那么一旦服務(wù)器進程退出,服務(wù)器中的數(shù)據(jù)庫狀態(tài)也會消失攀芯,所以Redis提供了持久化功能屯断!

RDB(默認(rèn)RDB,一般情況下不需要修改配置)

在指定的時間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤,也就是快照殖演。它恢復(fù)時是將快照文件直接讀到內(nèi)存里氧秘。

redis會單獨創(chuàng)建一個子進程來進行持久化,先將數(shù)據(jù)寫入一個臨時文件中趴久,待持久化過程結(jié)束丸相,在用臨時文件替換上次持久化好的文件。整個過程中彼棍,主進程是不進行任何IO操作的灭忠。這就確保了極高的性能。

如果需要進行大規(guī)模數(shù)據(jù)的恢復(fù)座硕,且對于數(shù)據(jù)恢復(fù)的完整性不是非常敏感弛作,那RDB方式要比AOF方式更加搞笑。

RDB的缺點是最后一個持久化后的數(shù)據(jù)可能丟失华匾。

rdb保存的文件是dump.rdb映琳,在配置文件中的快照進行配置

觸發(fā)機制

save的規(guī)則滿足的情況下,會自動觸發(fā)rdb規(guī)則

執(zhí)行flushall命令蜘拉,也會觸發(fā)rdb規(guī)則萨西!

退出redis,也會產(chǎn)生rdb文件

備份會自動生成一個dump.rdb

如何恢復(fù)rdb文件旭旭!

只需要將rdb文件放在我們的redis啟動目錄就可以谎脯,redis啟動時會自動檢查dump.rdb并恢復(fù)其中的數(shù)據(jù)

優(yōu)點

適合大規(guī)模的數(shù)據(jù)恢復(fù)!

對數(shù)據(jù)的完整性要求不高持寄!

缺點

需要一定的時間間隔進行操作源梭!如果redis宕機了,這個最后一次修改的數(shù)據(jù)就沒有了

fork進程的時候际看,會占用一定的內(nèi)存空間

AOF(Append Only File)

將所有命令都記錄下來咸产,恢復(fù)的時候會把這個文件全部執(zhí)行一遍

以日志的形式來記錄每個寫操縱,將Redis執(zhí)行過的所有指令記錄下來(讀操作不記錄)仲闽,只許追加文件但不可以改寫文件脑溢,redis啟動之初會讀取該文件重新構(gòu)建數(shù)據(jù),換言之赖欣,Redis重啟的話就根據(jù)日志文件的內(nèi)容將寫指令從前到后執(zhí)行一次以完成數(shù)據(jù)的恢復(fù)工作

Aof保存的文件是appendonly.aof文件

redis默認(rèn)不開啟aof屑彻,需要手動修改配置文件!將appendonly改為yes才能開啟aof

如果aof文件有問題顶吮,無法重新啟動redis服務(wù)社牲,需要用redis-check-aof --fix appendonly-aof

如果aof文件大于64m!fork一個新的進程來將文件進行重寫

優(yōu)點和缺點

優(yōu)點:

每一次修改都同步悴了,文件的完整性更好

默認(rèn)每秒同步一次搏恤,可能會丟失一秒的數(shù)據(jù)

若從不同步违寿,效率最高!

缺點:

相對于數(shù)據(jù)文件來說熟空,aof遠(yuǎn)遠(yuǎn)大于rdb藤巢,修復(fù)的速度也比rdb慢!

Aof運行的效率也要比rdb慢息罗,所以redis默認(rèn)的持久化方式是rdb掂咒!

擴展:

RDB持久化方式能夠在指定的時間間隔內(nèi)對數(shù)據(jù)進行快照存儲

AOF持久化方式記錄每次對服務(wù)器的寫操作,當(dāng)服務(wù)器重啟的時候回重新執(zhí)行這些命令來恢復(fù)原始數(shù)據(jù)迈喉,AOF命令以Redis協(xié)議追加保存每次寫的操作到文件末尾绍刮,Redis還能對aof文件進行后臺重寫,防止aof文件體積不至于過大挨摸。

只做緩存孩革,不需要使用任何持久化

同時開啟兩種持久化方式

在這種情況下當(dāng)redis重啟的時候會優(yōu)先載入aof文件來恢復(fù)原始數(shù)據(jù),因為在通常情況下aof文件保存的數(shù)據(jù)集要比RDB文件保存的數(shù)據(jù)集完整

RDB的數(shù)據(jù)不實時油坝,同時使用兩者時服務(wù)器重啟也只會找AOF文件嫉戚,不建議只使用AOF,因為RDB更適合用于數(shù)據(jù)備份(AOF在不斷變化不好備份)澈圈,快速重啟,而且不會有AOF可能潛在的Bug帆啃,留著作為一個萬一的手段瞬女。

性能建議

因為RDB文件只用作備份用途,建議只在Slave(從盤)上持久化RDB文件努潘,而且只要15分鐘備份一次即可诽偷,只保留 save 900 1(15分鐘至少修改一條就開啟備份)這個規(guī)則。

如果Enable AOF,好處是在最惡劣情況下也只會丟失不超過兩秒數(shù)據(jù)疯坤,啟動腳本較簡單只load自己的AOF文件就可以了报慕,代價一是帶來了持續(xù)的IO,二是AOF rewirte的最后將重寫過程中產(chǎn)生的新數(shù)據(jù)寫到新文件造成的阻塞幾乎是不可避免的压怠。只要硬盤許可眠冈,應(yīng)該盡量減少AOF重寫的頻率,AOF重寫的基礎(chǔ)大小默認(rèn)值64M太小了菌瘫,可以設(shè)置到5G以上蜗顽,默認(rèn)超過原大小100%重寫可以改到適當(dāng)?shù)臄?shù)值。

如果不開啟AOF雨让,僅靠Master-Slave(主從復(fù)制) Repllcation實現(xiàn)高可用性也可以雇盖,能減少很多IO操作,也減少了重寫時帶來的系統(tǒng)波動栖忠,代價是Master/Slave同時宕機(斷電)崔挖,會丟失十幾分鐘的數(shù)據(jù)贸街,啟動腳本也要比較兩個Master/Slave中的RDB文件,載入較新的那個狸相,微博就是這種架構(gòu)薛匪。

Redis發(fā)布訂閱

Redis發(fā)布訂閱(pub/sub)是一種消息通信模式:發(fā)送者(pub)發(fā)送消息,訂閱者(sub)接收消息卷哩。微信蛋辈,微博,關(guān)注系統(tǒng)将谊!

Redis客戶端可以訂閱任意數(shù)量的頻道冷溶。

訂閱/發(fā)布消息圖:

發(fā)布訂閱原理

測試

訂閱端:

127.0.0.1:6379> SUBSCRIBE wirdeos#訂閱一個頻道

Reading messages... (press Ctrl-C to quit)

1)"subscribe"

2)"wirdeos"

3) (integer)1

#等待讀取推送的信息

1)"message"#消息

2)"wirdeos"#頻道

3)"1231341"#內(nèi)容

發(fā)送端:

127.0.0.1:6379> PUBLISH wirdeos 1231341 #發(fā)送者發(fā)送消息到頻道!

(integer) 1

原理

Redis是使用C實現(xiàn)的尊浓,通過分析Redis源碼里的pubsub.c文件逞频,了解發(fā)布和訂閱機制的底層實現(xiàn),籍此加深對Redis的理解栋齿。

Redis通過PUBLISH,SUBSCRIBE和PSUBSCRIBE等命令實現(xiàn)發(fā)布和訂閱功能苗胀。

通過SUBSCRIBE命令訂閱某頻道后,redis-server里維護了一個字典瓦堵,字典的鍵就是一個個channel基协,而字典的值則是一個鏈表,鏈表中保存了所有訂閱這個channel客戶端菇用。SUBSCRIBE命令的關(guān)鍵澜驮,就是將客戶端添加到給定channel的訂閱鏈表中。

通過PUBLISH命令向訂閱者發(fā)送消息惋鸥,redis-server會使用給定的頻道作為鍵杂穷,在它所維護的channel字典中查找記錄了訂閱這個頻道的所有客戶端鏈表,遍歷這個鏈表卦绣,將消息發(fā)布給所有訂閱者

Pub/Sub從字面理解就是發(fā)布(Publish)與訂閱(Subscribe)耐量,在Redis中可以設(shè)定對某一個key值進行消息發(fā)布及消息訂閱,當(dāng)一個key值上進行了消息發(fā)布后滤港,所有訂閱他的客戶端都會收到相應(yīng)的消息廊蜒。這一功能最明顯的用法就是用作實時消息系統(tǒng)胆建,比如普通的即使聊天正驻,群聊等。

使用場景:

實時消息系統(tǒng)陨闹!

實時聊天樟凄!

訂閱關(guān)注系統(tǒng)聘芜!

Redis主從復(fù)制

主從復(fù)制,是指將一臺Redis服務(wù)器的數(shù)據(jù)缝龄,復(fù)制到其他的Redis服務(wù)器汰现。前者成為主節(jié)點(Master/leader)挂谍,后者稱為從節(jié)點(slave/follower);數(shù)據(jù)的復(fù)制是單向的,只能由主節(jié)點到從節(jié)點瞎饲。Master以寫為主口叙,Slave以讀為主。

默認(rèn)情況下嗅战,每臺Redis服務(wù)器都是主節(jié)點妄田;且一個主節(jié)點可以有多個從節(jié)點(或沒有),但一個從節(jié)點只可以有一個主節(jié)點驮捍。

主從復(fù)制的作用主要包括:

數(shù)據(jù)冗余(重復(fù)數(shù)據(jù)):主從復(fù)制實現(xiàn)了數(shù)據(jù)的熱備份疟呐,是持久化之外的一種數(shù)據(jù)冗余方式。

故障恢復(fù):當(dāng)主節(jié)點出現(xiàn)問題時东且,可以由從節(jié)點提供服務(wù)启具,實現(xiàn)快速的故障恢復(fù);實際上是一種服務(wù)的冗余

負(fù)載均衡:在主從復(fù)制的基礎(chǔ)上珊泳,配合讀寫分離鲁冯,可以由主節(jié)點提供寫服務(wù),由從節(jié)點提供讀服務(wù)(即寫數(shù)據(jù)時應(yīng)用連接主節(jié)點色查,讀Redis數(shù)據(jù)應(yīng)用連接從節(jié)點)薯演,分擔(dān)服務(wù)器負(fù)載;尤其是在寫少讀多的場景下秧了,通過多個從節(jié)點分擔(dān)讀負(fù)載涣仿,可以大大提高Redis服務(wù)器的并發(fā)量。

高可用(集群)基石:除了上述作用以外示惊,主從復(fù)制還是哨兵和集群能夠?qū)嵤┑幕A(chǔ),因此說主從復(fù)制時Redis高可用的基礎(chǔ)愉镰。

最少米罚,一主二從

一般來說,要將redis運用于工程項目中丈探,只用一臺redis是不夠的录择,原因如下:

從結(jié)構(gòu)上,單個Redis服務(wù)器會發(fā)色單點故障碗降,并且一臺服務(wù)器需要處理所有的請求負(fù)載隘竭,壓力較大;

從容量上讼渊,單個Redis服務(wù)器內(nèi)部容量有限动看,無法將所有內(nèi)存用作Redis存儲內(nèi)存。一般來說爪幻,單臺Redis的最大使用內(nèi)存不應(yīng)該超過20G

環(huán)境配置

只配置從庫菱皆,不用配置主庫须误!

[root@localhost bin]# redis-server wconfig/redis.conf

[root@localhost bin]# redis-cli -p 6379

127.0.0.1:6379> info replication#查看當(dāng)前庫的信息

# Replication

role:master

connected_slaves:0#從機個數(shù)

master_failover_state:no-failover

master_replid:578832bddda2f86b82bf1cf619620397a44c0d98

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:0

second_repl_offset:-1

repl_backlog_active:0

repl_backlog_size:1048576

repl_backlog_first_byte_offset:0

repl_backlog_histlen:0

賦值配置文件,修改對應(yīng)的信息

端口

pid名字

log文件名字

dump.rdb名字

redis集群環(huán)境

一主二從

默認(rèn)情況下仇轻,每臺Redis服務(wù)器都是主節(jié)點京痢;一般情況下只需要配置從機就好了!

SLAVEOF 主機ip 端口號#在從機中配置

真實的主從配置應(yīng)該在配置文件中配置篷店,這樣才是永久的祭椰,使用命令配置是暫時的.

主從復(fù)制配置文件

細(xì)節(jié)

主機可以寫,從機只能讀疲陕!主機中的所有信息和數(shù)據(jù)方淤,都會自動的被從機保存

測試:主機斷開連接,從機依舊連接到主機鸭轮,但是沒有寫操作臣淤;主機如果重連,從機依舊可以獲取主機寫入的信息

如果是使用命令行配置主從窃爷,如果重啟從機邑蒋,從機就會變回主機。如果重新設(shè)置成從機按厘,那么還可以獲取主機數(shù)據(jù)

復(fù)制原理

從機啟動成功連接到主機后會發(fā)送一個同步命令

主機接到命令医吊,啟動后臺的存盤進程,同時收集所有接受到的用于修改數(shù)據(jù)集命令逮京,在后臺進程執(zhí)行完畢之后主機將整個數(shù)據(jù)文件傳到從機卿堂,并完成一次完全同步。

全量賦值:從機服務(wù)在接收到數(shù)據(jù)庫文件數(shù)據(jù)后懒棉,將其存盤并加載到內(nèi)存中

增量賦值:主機繼續(xù)將新的所有收集到的修改命令一次傳給從機完成同步

但是只要重新連接主機草描,一次完全同步(全量復(fù)制)將被自動執(zhí)行!數(shù)據(jù)一定可以在從機中看到

模式1
模式2

這個時候也可以完成主從復(fù)制

如果主節(jié)點斷開策严,這個時候只能手動完成(沒有哨兵模式)

SLAVEOF on one穗慕;若主機斷開,將從節(jié)點設(shè)置成主節(jié)點妻导!其他的結(jié)點就可以手動操作到主節(jié)點

哨兵模式(redis2.8開始提供)

概述

能夠后臺監(jiān)控主機是否故障逛绵,如果故障了根據(jù)投票數(shù)自動將從庫轉(zhuǎn)為主庫

哨兵模式是一種特殊的模式,首先Redis提供了哨兵的命令倔韭,哨兵是一個獨立的進程术浪,作為進程,它會獨立運行寿酌。其原理是哨兵通過發(fā)送命令胰苏,等待Redis服務(wù)器響應(yīng),從而監(jiān)控運行多個Redis實例份名。

哨兵模式原理圖

這里的哨兵有兩個作用

通過發(fā)送命令碟联,讓Redis服務(wù)器返回監(jiān)控其運行狀態(tài)妓美,包括主服務(wù)器和從服務(wù)器

當(dāng)哨兵監(jiān)測到master宕機,會自動將slave切換成master鲤孵,然后通過發(fā)布訂閱模式通知其他的從服務(wù)器壶栋,修改配置文件,讓它們切換主機

然而一個哨兵進程對Redis服務(wù)器進行監(jiān)控普监,可能會出現(xiàn)問題贵试,因此可以采用多哨兵進行監(jiān)控。各個哨兵之間還會進行監(jiān)控凯正,這樣就形成了多哨兵模式毙玻。

多哨兵模式

假設(shè)主服務(wù)器宕機,哨兵1先檢測到這個結(jié)果廊散,系統(tǒng)不會馬上進行重新選舉的過程桑滩,僅僅是哨兵1主觀的認(rèn)為主服務(wù)器不可用,這個現(xiàn)象稱為主觀下線允睹。當(dāng)后面的哨兵也檢測到主服務(wù)器不可用运准,并且數(shù)量達(dá)到一定值時,那么哨兵之間就會進行一次投票缭受,投票的結(jié)果由一個哨兵發(fā)起胁澳,進行故障轉(zhuǎn)移操作。切換成功后米者,就會通過發(fā)布訂閱模式韭畸,讓各個哨兵把自己監(jiān)控的從服務(wù)器實現(xiàn)切換主機,這個過程成為客觀下線蔓搞。

哨兵配置

[root@localhost wconfig]# vim sentinel.conf #在配置文件目錄下新建哨兵配置文件

#sentinel monitor 被監(jiān)控的名稱? host port 1 #開啟投票

sentinel monitor myredis127.0.0.163791

啟動哨兵

[root@localhost bin]# redis-sentinel wconfig/sentinel.conf

[root@localhost bin]# redis-sentinel wconfig/sentinel.conf

3450:X23Mar202114:01:35.952# oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo

3450:X23Mar202114:01:35.952# Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=3450, just started

3450:X23Mar202114:01:35.952# Configuration loaded

3450:X23Mar202114:01:35.953 * Increased maximum number of open files to10032(it was originallysetto1024).

3450:X23Mar202114:01:35.953 * monotonic clock: POSIX clock_gettime

? ? ? ? ? ? ?? _._ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

_.-``__''-._

_.-```.? `_.''-._ ? ? ? ? ? Redis6.2.1 (00000000/0)64bit

.-``.-```.? ```\/ ?? _.,_''-._

(' ? ?? , ? ? ? .-`? | `, ?? ) ? ? Running in sentinel mode

|`-._`-...-` __...-.``-._|'`_.-'| ? ? Port: 26379

|`-._ ? `._ ?? / ? ? _.-' ?? | ? ? PID: 3450

`-._ ?? `-._`-./? _.-' ?? _.-' ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

|`-._`-._`-.__.-' ?? _.-'_.-'| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

|`-._`-._ ? ? ?? _.-'_.-'| ? ? ? ? ? http://redis.io

`-._ ?? `-._`-.__.-'_.-' ?? _.-' ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

|`-._`-._`-.__.-' ?? _.-'_.-'| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

|`-._`-._ ? ? ?? _.-'_.-'|

`-._ ?? `-._`-.__.-'_.-' ?? _.-' ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

`-._ ?? `-.__.-' ?? _.-'

`-._ ? ? ?? _.-' ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

`-.__.-' ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

3450:X23Mar202114:01:35.954# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

3450:X23Mar202114:01:35.955# Sentinel ID is 80bbca2a11769d234d3cfb2b826429af2ae27f80

3450:X23Mar202114:01:35.955# +monitor master myredis 127.0.0.1 6379 quorum 1

3450:X23Mar202114:01:35.956 *+slave slave127.0.0.1:6380127.0.0.16380@ myredis127.0.0.16379

3450:X23Mar202114:01:35.965 *+slave slave127.0.0.1:6381127.0.0.16381@ myredis127.0.0.16379

如果主機宕機胰丁,哨兵會自動選出新的主機并做好遷移處理,而原主機重連之后喂分,只能歸并到新的主機下變?yōu)閺臋C

哨兵模式

優(yōu)點:

哨兵集群基于主從復(fù)制模式隘马,所有的主從配置優(yōu)點全都有

主從可以切換,故障可以轉(zhuǎn)義妻顶,系統(tǒng)可用性會更好

哨兵模式類似于主從模式的升級,從手動到自動蜒车,健壯性更好

缺點:

Redis不好在線擴容讳嘱,集群容量一旦到達(dá)上線,在線擴容十分麻煩酿愧!

實現(xiàn)哨兵模式的配置很麻煩沥潭,選擇比較多

哨兵模式的全部配置

# Example ? sentinel.conf

# 哨兵sentinel實例運行的端口 ? 默認(rèn)是26379,如果有哨兵集群嬉挡,還需要配置每個哨兵端口

port26379

#哨兵sentinel的工作目錄

dir /tmp

#哨兵 sentine1 監(jiān)控的redis主節(jié)點的 ip port ?

# master-name? 钝鸽,可以自己命名的主節(jié)點名字 只能由字母A-Z汇恤、數(shù)字0-9、這三個字符"? . ? -? _ "組成拔恰。

# quorum配置多少個sentine1哨兵統(tǒng)- -認(rèn)為master主節(jié)點失聯(lián)那么這時客觀上認(rèn)為主節(jié)點失聯(lián)了

# sentine1 monitor <master-name> <ip> <redis-port> <quorum>

sentinel monitor mymaster127.0.0.163792

#當(dāng)在Redis實例中開啟了requirepass foobared 授權(quán)密碼這樣所有連接kedis實例的客戶端都要提供密碼

#設(shè)置哨兵sentinel連接主從的密碼注意必須為主從設(shè)置- - 樣的驗證密碼

# sentine1 auth-pass <master-name> <password>

sentine1 auth-pass mymaster MySUPER--secret-0123passwOrd

#指定多少毫秒之后主節(jié)點沒有應(yīng)答哨兵sentine1 此時哨兵主觀上認(rèn)為主節(jié)點下線默認(rèn)30秒

# sentinel down-after-mi 11i seconds <master-name> <mi 11iseconds>

sentine1 down-after-mi 11iseconds mymaster30000

#這個配置項指定了在發(fā)生failover主備切換時最多可以有多少個slave同時對新的master進行同步因谎,

這個數(shù)字越小,完成fai lover所需的時間就越長颜懊,

但是如果這個數(shù)字越大财岔,就意味著越多的slave因為replication而 不可用。

可以通過將這個值設(shè)為1來保證每次只有一個slave處于不能處理命令請求的狀態(tài)河爹。

# sentine1 paralle1-syncs <master-name> <numslaves>

sentine1 paralle1-syncs mymaster1

#故障轉(zhuǎn)移的超時時間failover-timeout 可以用在以下這些方面:

#1.同一個sentine1對同一 個master兩次fai lover之間的間隔時間匠璧。

#2.當(dāng)一個slave從一 個錯誤的master那里同步數(shù)據(jù)開始計算時間。直到s1ave被糾正為向正確的master那里同步數(shù)據(jù)時咸这。

#3.當(dāng)想要取消一個正在進行的failover所需要的時間夷恍。

#4.當(dāng)進行failover時,配置所有s1aves指向新的master所需的最大時間媳维。不過酿雪,即使過了這個超時,slaves 依然會被正確配置為指向master,但是就不按parallel-syncs所配置的規(guī)則來了

#默認(rèn)三分鐘

# sentine1 failover-timeout <master-name> <milliseconds>

sentine1 fai lover-ti meout mymaster180000

# SCRIPTS EXECUTION

#配置當(dāng)某一事件發(fā)生時所需要執(zhí)行的腳本侨艾,可以通過腳本來通知管理員执虹,例如當(dāng)系統(tǒng)運行不正常時發(fā)郵件通知相關(guān)人員。

#對于腳本的運行結(jié)果有以下規(guī)則:

#若腳本執(zhí)行后返回1唠梨,那么該腳本稍后將會被再次執(zhí)行袋励,重復(fù)次數(shù)目前默認(rèn)為10

#若腳本執(zhí)行后返回2,或者比2更高的一個返回值当叭,腳本將不會重復(fù)執(zhí)行茬故。

#如果腳本在執(zhí)行過程中由于收到系統(tǒng)中斷信號被終止了,則同返回值為1時的行為相同蚁鳖。

#一個腳本的最大執(zhí)行時間為60s磺芭,如果超過這個時間,腳本將會被-一個SIGKILL信號終止醉箕,之后重新執(zhí)行钾腺。

#通知型腳本:當(dāng)sentine1有任何警告級別的事件發(fā)生時(比如說redis實例的主觀失效和客觀失效等等),將會去調(diào)用這個腳本讥裤,這時這個腳本應(yīng)該通過郵件放棒,SMS等 方式去通知系統(tǒng)管理員關(guān)于系統(tǒng)不正常運行的信息。調(diào)用該腳本時己英,將傳給腳本兩個參數(shù)间螟,一 個是事件的類型,一個是事件的描述。如果sentine1. conf配置文件中配置了這個腳本路徑厢破,那么必須保證這個腳本存在于這個路徑荣瑟,并且是可執(zhí)行的,否則sentine1無法正常啟動成功摩泪。

#通知腳本

# she11編程

# sentine1 notification-script <master-name> <script-path>

sentine1 notificati on-script mymaster /var/redis/notify.sh

#客戶端重新配置主節(jié)點參數(shù)腳本

#當(dāng)一個master由于failover而發(fā)生改變時笆焰,這個腳本將會被調(diào)用,通知相關(guān)的客戶端關(guān)于master地址已經(jīng)發(fā)生改變的信息加勤。

#以下參數(shù)將會在調(diào)用腳本時傳給腳本:

# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>

#目前<state>總是“failover",

# <role>是“Teader"或者"observer"中的-一個仙辟。

#參數(shù)from-ip, from-port鳄梅, to-ip叠国,to-port是用來和舊的master和新的master(即舊的s lave)通信的

#這個腳本應(yīng)該是通用的,能被多次調(diào)用戴尸,不是針對性的粟焊。

# sentine1 client-reconfig-script <master-name> <script-path>

sentine1 client-reconfig-script mymaster /var/redis/reconfig.sh#一般都是由運維來配置!

Redis緩存穿透和雪崩

緩存穿透(查不到)

概念

緩存穿透,就是查一個數(shù)據(jù)緩存中沒有孙蒙,然后向數(shù)據(jù)庫中查詢项棠。發(fā)現(xiàn)數(shù)據(jù)庫也沒有,因此查詢失敗挎峦。而當(dāng)數(shù)據(jù)訪問量特別大的時候香追,會對數(shù)據(jù)庫造成很大壓力,出現(xiàn)了緩存穿透坦胶。

解決方案

布隆過濾器

布隆過濾器是一種數(shù)據(jù)結(jié)構(gòu)透典,對所以可能查詢的參數(shù)以hash形式存儲,在控制層先進行校驗顿苇,不符合則丟棄峭咒,從而避免了對底層存儲系統(tǒng)的查詢壓力。

布隆過濾器

優(yōu)缺點

優(yōu)點:由于存放的不是完整數(shù)據(jù)纪岁,所以占用內(nèi)存少凑队,而且新增,查詢速度快

缺點:鎖著數(shù)據(jù)的增加幔翰,誤判率會隨之增加漩氨;無法做到刪除數(shù)據(jù);也就是說布隆過濾器說不存在就一定不存在遗增,說存在那么是可能存在才菠。

緩存空對象

當(dāng)存儲曾不命中后,即使返回空對象也將其緩存起來贡定,同時或設(shè)置一個過期時間,之后再訪問這個數(shù)據(jù)將會從緩存中獲取可都,不會再訪問數(shù)據(jù)庫缓待。

緩存空對象存在問題

如果空值可以被緩存蚓耽,這就意味著需要更多的空間存儲更多的鍵,因為空值的鍵可能會占用很大空間

即使對空值設(shè)置過期時間旋炒,還是會存在緩存和數(shù)據(jù)庫的數(shù)據(jù)會有一段時間窗口不一致步悠,對數(shù)據(jù)的一致性會有影響

緩存擊穿(庫有緩存無,量大)

概述

緩存擊穿指一個key非常熱點瘫镇,在高并發(fā)的環(huán)境下鼎兽,緩存中查不到,但是數(shù)據(jù)庫中可以查到铣除,導(dǎo)致所有訪問都進入到數(shù)據(jù)庫中谚咬,數(shù)據(jù)庫瞬間壓力過大。

解決方案

設(shè)置value永不過期

加互斥鎖(類似synchronized)

分布式鎖:使用分布式鎖尚粘,保證對于每個key同一時間只有一個線程去查詢后端服務(wù),其他線程只能等待择卦。將高并發(fā)的壓力轉(zhuǎn)移到分布式鎖,因此對于分布式鎖的考驗很大

緩存雪崩

概述

緩存雪崩郎嫁,指同一時間緩存大量失效秉继,到時大量訪問全部進入數(shù)據(jù)庫,可能會造成數(shù)據(jù)庫崩潰進而導(dǎo)致網(wǎng)站崩潰

解決方案

Redis高可用-搭建集群

限流降級

數(shù)據(jù)預(yù)熱

正式部署之前泽铛,先把可能的數(shù)據(jù)預(yù)先訪問一遍尚辑,這樣部分可能大量訪問的數(shù)據(jù)就會加載到緩存中。在即將發(fā)生高并發(fā)訪問錢手動觸發(fā)加載緩存不同的key盔腔,設(shè)置不同的過期時間杠茬,讓緩存失效的時間點盡量均勻

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市铲觉,隨后出現(xiàn)的幾起案子澈蝙,更是在濱河造成了極大的恐慌,老刑警劉巖撵幽,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灯荧,死亡現(xiàn)場離奇詭異,居然都是意外死亡盐杂,警方通過查閱死者的電腦和手機逗载,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來链烈,“玉大人厉斟,你說我怎么就攤上這事∏亢猓” “怎么了擦秽?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我感挥,道長缩搅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任触幼,我火速辦了婚禮硼瓣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘置谦。我一直安慰自己堂鲤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布媒峡。 她就那樣靜靜地躺著瘟栖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丝蹭。 梳的紋絲不亂的頭發(fā)上慢宗,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天,我揣著相機與錄音奔穿,去河邊找鬼镜沽。 笑死,一個胖子當(dāng)著我的面吹牛贱田,可吹牛的內(nèi)容都是我干的缅茉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼男摧,長吁一口氣:“原來是場噩夢啊……” “哼蔬墩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起耗拓,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤拇颅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后乔询,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體樟插,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年竿刁,在試婚紗的時候發(fā)現(xiàn)自己被綠了黄锤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡食拜,死狀恐怖鸵熟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情负甸,我是刑警寧澤流强,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布痹届,位于F島的核電站,受9級特大地震影響打月,放射性物質(zhì)發(fā)生泄漏短纵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一僵控、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鱼冀,春花似錦报破、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至荸型,卻和暖如春盹靴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瑞妇。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工稿静, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辕狰。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓改备,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蔓倍。 傳聞我的和親對象是個殘疾皇子悬钳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容