為什么使用nosql:
關(guān)系數(shù)據(jù)庫的缺點:
1.無法處理每秒上萬次的qps,優(yōu)于關(guān)系數(shù)據(jù)庫沒有大量的io局蚀,硬盤io位性能瓶頸
2關(guān)系型數(shù)據(jù)庫表字段有限,記錄數(shù)量有限,最多256列棵介,當表數(shù)據(jù)到達百萬讀寫速度下降
3無法簡單的通過增加硬件,服務(wù)節(jié)點來提高系統(tǒng)性能
nosql的優(yōu)點:
1支持高并發(fā)吧史,數(shù)據(jù)存于內(nèi)存邮辽,讀寫性能高
2無需事先建立字段,隨時存儲自定義的數(shù)據(jù)格式,在關(guān)系型數(shù)據(jù)庫中必須實現(xiàn)添加好字段
3.高可用吨述,支持實現(xiàn)高可用架構(gòu)岩睁,哨兵/集群cluster 等
4成本低開源基本不收費
nosql的缺點:
1.沒有約束沒有索引
2.沒有標準的sql語句
3.數(shù)據(jù)之間無聯(lián)系
redis的安裝及下載
linux安裝:
下載redis的壓縮包(自行百度)并解壓,因為redis是c編寫的需要c的編譯器揣云,安裝gcc捕儒,yum -y install gcc
到/root/redis/redis-3.2.9/src以下目錄執(zhí)行? make命令 編譯c文件,至此安裝完成
啟動redis:到redis-3.2.9/src 下執(zhí)行 ./redis-server &
關(guān)閉redis:到redis-3.2.9/src 下執(zhí)行./redis-cli shutdown? 可以直接輸入也可以在client端直接關(guān)掉(處理邏輯是先拒絕請求把當前數(shù)據(jù)處理完關(guān)閉程序)
客戶端鏈接
QPS10w
1.直接啟動 ./redis-cli
2.指定所要鏈接的redis? ./redis -cli -h 127.0.0.1 -p 6379
redis的基本命令
ping : 判斷網(wǎng)絡(luò)是否通
dbsize:查看當前數(shù)據(jù)庫的key的數(shù)目
redis默認使用16個庫邓夕,從0-15 對數(shù)據(jù)庫的修改可以在redis-conf中的database 16
切換數(shù)據(jù)庫:select db 選擇第6個庫 select 5
刪除當前的數(shù)據(jù)庫 flushdb
redis的key的操作命令
1.keys pattern 查找符合pattern的key值刘莹。partten可以使用通配符
如:keys *
如:keys zhang?an
2.exists: exists key【key】判斷key是否存在焚刚,存在返回1点弯,其他返回0,當使用多個key值時候矿咕,返回key的數(shù)量
3.expire :expire key seconds 設(shè)置key的生存時間秒 抢肛,超過時間key自動刪除,設(shè)置成功返回1其他情況返回0
4.ttl key:以s為單位查看key的剩余存活時間碳柱,
-1表示永不過期
-2表示不存在
其余數(shù)字以s為單位表示剩余時間
redis的五種數(shù)據(jù)類型:
String:存儲字符串捡絮,包括二進制及序列化后的數(shù)據(jù) 最大存儲512m
語法:set/get/incr(數(shù)字類型+1)/decr(數(shù)字類型-1)/append 在原來key基礎(chǔ)上加value返回value長度,
strlin key:返回key 所存儲的字符串的長度
getrange key start end: 截取字符串士聪,返回截取的字符串
setrange key offset value:用value替換key的存儲的值從offset開始锦援,不存在的當空字符串處理
mset 同時設(shè)置多個key 同理 mget 同時取多個value
(簡單語法沒有截圖,如果需要請留言)
hash:是一個string類型的field和value的映射表
語法:hset/hget /hmset(存多個value)/hmget
hmget key field ... 指定多個field剥悟,空field返回null
hgetall key 返回所有的key的filed 及 value
hkeys:看所有的field列表
hvals key:返回hash表中所有域的值
hexists:查看給定的field是否存在灵寺,存在返回1不存在返回0
list:簡單的字符串列表,按照插入順序排序区岗,可以從左從右添加
語法:lpush/rpush/lrange key start stop -1表示最后一個數(shù)字
lindex key index 獲取key中下標為index的元素 lrang zhangfan(key) 0 4
llen key:獲取列表key的長度
lrem key count value:根據(jù)count刪除value的值略板,count>0從左側(cè)刪除counts數(shù)量的value,反之從右邊慈缔,若count =0 刪除所有value叮称、
lset key index value,將第幾位的值改為value的值
set(無序):是string類型的無序集合藐鹤,集合成員是唯一的瓤檐、
語句:sadd/smembers/scard key/srem key member(刪除key中的一個或多個value)/
srandmember key {count}隨機返回一個數(shù)據(jù) 有count返回count的數(shù)據(jù)、
spop key 【count】 刪除一個隨機元素娱节,有count刪除隨機的count的值
zset:與set一樣也是string的無序集合挠蛉,且不允許重復(fù)的成員,不同點是每一個元素都關(guān)聯(lián)一個分數(shù)肄满,redis會根據(jù)分樹進行排序
語法 zadd:zdd key score member 【谴古。质涛。。掰担。汇陆。】
查詢zrange -1 表示最后一個带饱,其余的跟之前是一樣的
zrevrange key start stop [withscores]:指定區(qū)間的score及value返回毡代,按照score從高到底
zrem key member 【。勺疼。月趟。。恢口。。穷躁。耕肩。】:刪除一個或者多個成員问潭,不存在即被忽略
zrangebyscore key min max 【withscores】 【limit offset count】:獲取有序集中所有的score介于min和滿之間的
zount key min max :score值在【min及max】之間成員的數(shù)量
新增:
經(jīng)緯度的數(shù)據(jù)類型:(geospatial)()
geoadd location 1.0.0.0 2.0.0.0 home(設(shè)置經(jīng)緯度)
geopos location home(獲取經(jīng)緯度)
新增hyperloglogs(奇數(shù)統(tǒng)計){1.1.2.4} 有四個
使用非常小的內(nèi)存統(tǒng)計非常大的數(shù)據(jù)量
redis訂閱通知猿诸,消息隊列
使用subscribe (具體頻道) psubscribe(可使用通配符頻道)
pubulish:發(fā)布消息
redis事務(wù)
redis的事務(wù)理解:保證事務(wù)的多條命令都能正常執(zhí)行,沒有回滾的概念
multi:標志一個事物的開始狡忙,將多條命令放到隊列里進行緩存
exec:執(zhí)行事務(wù)中的每條命令梳虽,相當于執(zhí)行隊列中的每條命令,如果事務(wù)被打斷灾茁,返回nil
discard:取消事務(wù)的所有的命令
* 事務(wù)執(zhí)行之前如果有命令執(zhí)行錯誤(語法有錯)窜觉,無法執(zhí)行此事務(wù),整個事務(wù)被放棄
* 放入事務(wù)中的命令北专,語法沒錯但是執(zhí)行時候出現(xiàn)錯誤禀挫,此時事務(wù)正常提交的并執(zhí)行
?Redis的watch機制
watch機制:監(jiān)聽一個或者多個key,如果key的value在exec執(zhí)行之前被修改了拓颓,整個事務(wù)被取消语婴,watch機制使得事務(wù)的exec變成有條件的,事務(wù)只有在被watch的key沒有被修改的前提下才會執(zhí)行
語法:watch key驶睦。砰左。。场航。/unwatch key缠导。。旗闽。酬核。
為什么使用lua腳本:
好處:一次發(fā)送多個命令蜜另,減少與服務(wù)端鏈接,減少網(wǎng)絡(luò)開銷
原子性
lua files復(fù)雜的命令嫡意,命令集的復(fù)用
eval lua-script key-num[key1 key2]
因為是單線程lua腳本萬一死循環(huán)會是其他命令都不能執(zhí)行
配置文件:超時時間举瑰,接受命令不執(zhí)行,不能中斷保持原子性
redis事務(wù)失敗為什么不會滾?
redis的持久化
redis4.0 以后支持混合持久化此迅;rdb會丟失大量數(shù)據(jù),aof文件過大旧巾,啟動會過慢耸序,所以有以下的結(jié)構(gòu)將rdb 文件 內(nèi)容和增量的aof文件進行存儲,此處aof不再是全量的文件鲁猩,而是增量的aof的文件
RDB:
在指定的時間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集以快照的形式存到磁盤中坎怪,需要數(shù)據(jù)恢復(fù)時直接將快照文件讀取到內(nèi)存中,存儲的是一個二進制文件廓握,默認是dump.rdb
rdb支持多個條件同時生效
AOF
每次接收到一條改變數(shù)據(jù)的命令時男应,他將命令寫到一個aof文件中,當redis重啟的時候娱仔,會通過執(zhí)行aof中每一條命令來回復(fù)數(shù)據(jù)沐飘。
優(yōu)先使用aof進行數(shù)據(jù)回復(fù)
如何實現(xiàn):
aof重寫的時候脚乡,有新的指令來蜒滩,會放到aof的緩存中,當aof重寫完成奶稠,將緩存的數(shù)據(jù)放到新的重寫文件中
redis的主從復(fù)制
master用于寫俯艰,slave只負責讀,向slave寫數(shù)據(jù)會報錯
主從復(fù)制的主要流程(全量同步/增量同步):
全量同步:主要發(fā)生在slave初始化的階段:slave會復(fù)制master上的所有的數(shù)據(jù)
1.slave > master 發(fā)送sync消息锌订;
2.master收到sync消息執(zhí)行bgsave生成RDB文件竹握。因為是異步操作,期間收到的請求放入到緩沖區(qū)中
3.master執(zhí)行完bgsave向salve發(fā)送快照
4.slave收到快照丟棄所有的舊數(shù)據(jù)辆飘,載入新的數(shù)據(jù)
5.salve接收完成后啦辐,讀取緩沖區(qū)中的命令
什么是bgsave:bgsave有個兄弟是save谓传,都是master執(zhí)行生成快照的命令,區(qū)別在于芹关,save會阻塞主主進程禁止其他訪問续挟,bgsave會fork一個子進程,去生成快照文件侥衬,os執(zhí)行此方法時候會使用寫時復(fù)制(copy - on - write)策略诗祸,即fork執(zhí)行的時候父子進程是公用同一套內(nèi)存,當父進程收到寫命令的時候會復(fù)制一份出來轴总,以保證子進程生成RDB文件不受影響直颅,所有fork的時候是fork某一刻的內(nèi)存數(shù)據(jù)。(快照:數(shù)據(jù)的二進制形式)
在一臺服務(wù)器上怀樟,修改配置文件可以模擬主從場景
單機場景下的容災(zāi)處理
了解(線上不會讓你自己去設(shè)置太low):如果master掛掉,就不能寫入只能讀取征堪,選一個slave執(zhí)行“slaveof no one ”將一個slave變成主服務(wù)器瘩缆,將另一臺slave重新掛載到新的master下 :slaveof 127.0.0.1 6381
Sentinel 哨兵模式
sentinel是一個sentine運行在特殊模式下的redis服務(wù)器
三個主要作用:
1.監(jiān)控主從服務(wù)器是否正常進行
2.提醒被監(jiān)控的redis出現(xiàn)問題,sentinel會通知其他程序
3.自動故障轉(zhuǎn)移
?工作機制: ?
sentinel會檢測master和slave是否正常佃蚜,如果某個sentinel掛了庸娱,就無法實現(xiàn)監(jiān)控所以哨兵一般要3個,當某一個sentinel認為被監(jiān)控的服務(wù)下線以后谐算,會向其他sentinel進行確認熟尉,判斷是否是真的下線?(主管下線 => 客觀下線)(超過半數(shù))(洲脂,對slave重新升為新的master斤儿,當原來的master重新上線時候成為slave
缺點:
切換的過程中可能出現(xiàn)數(shù)據(jù)的確實
寫入只能寫到一個mstaer,沒有辦法水平擴容(多個master)
分布式就是解決水平擴容
Sentinel 集群模式
哨兵模式可以實現(xiàn)高可用恐锦,但是要支持高并發(fā)往果,存儲海量數(shù)據(jù)還是不行,所以引入了redis集群
一個redis節(jié)點有多個node組成一铅,而多個node之間通過cluster meet命令來實現(xiàn)。
節(jié)點間的握手過程:
節(jié)點A收到客戶端的cluster meet命令。然后A收到ip和端口女气,向這個地址B節(jié)點發(fā)送一個消息,B回復(fù)一個pang掉缺,A收到以后回復(fù)一個ping,表名握手成功戈擒,最后眶明,A節(jié)點通過gossip協(xié)議將B節(jié)點的信息同步給其他節(jié)點C,D,E等
槽slot:
redis通過集群分片的形式保存數(shù)據(jù),存儲單位是槽slot峦甩,一共有16384個赘来,如果有3個節(jié)點的集群,那么每個集群都有5500左右的槽slot凯傲,添加/刪除節(jié)點的方式是:如新增一個4節(jié)點犬辰,1-3會勻出一些分配給4各個節(jié)點的槽點基本保持一致
處理數(shù)據(jù)流程:通過slot = CRC16(key)& 16383 (CRC16算法),計算數(shù)據(jù)在那個槽solt上冰单,然后進行數(shù)據(jù)處理
故障轉(zhuǎn)移
A > B 節(jié)點會進行通信如果A節(jié)點認為B節(jié)點離線了(發(fā)ping消息在cluster_node_timeout時間內(nèi)沒有返回)幌缝,會通知其他節(jié)點,其余節(jié)點如果都認為B節(jié)點離線(超過半數(shù)以上)诫欠,則B節(jié)點真正的離線涵卵。
然后會進行類似于raft算法,該節(jié)點上的slave會生成master
重定向
因為client鏈接redis的時候可以鏈接任何一個節(jié)點荒叼。所以在cluster模式的情況下當cliet進行請求的時候主要流程:
1.檢查當前的key是否存在當前節(jié)點(crc16)key / 16384
2.若不是該節(jié)點負責轿偎,返回moved重定向
3.該slot是否正在遷入或者遷出(遷入的solt有ASKING標記,直接進行操作被廓,若為正在遷出solt則重定向客戶端到遷移的目的服務(wù)器)