1. Redis學習筆記

        共 13350字,需瀏覽 27分鐘

         ·

        2021-05-23 06:03

        什么是Redis

        Redis是一個使用C語言編寫的,開源的(BSD許可)高性能非關系型(NoSQL)的鍵值對數(shù)據(jù)庫

        Redis可以存儲鍵和五種不同類型的值之間的映射。鍵的類型只能為字符串,值支持五種類型:字符串、列表、集合、散列表、有序集合


        與傳統(tǒng)數(shù)據(jù)庫不同的是Redis的數(shù)據(jù)是存在內(nèi)存中的,所以讀寫速度非常快,因此Redis被廣泛應用于緩存方向,每秒可處理10萬次讀寫操作
        Redis也可以用來做分布式鎖
        Redis支持事務、持久化、LUA腳本、LRU驅動事件、多種集群方案

        Redis的優(yōu)缺點

        優(yōu)點

        讀寫性能優(yōu)異
        支持數(shù)據(jù)持久化
        支持事務
        數(shù)據(jù)結構豐富
        支持主從復制

        缺點

        數(shù)據(jù)庫容量收到物理內(nèi)存的限制,不能用作海量數(shù)據(jù)的高性能讀寫,因此Redis適合場景主要局限于較小數(shù)據(jù)量的高性能操作和運算
        Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復
        主機宕機,宕機前有部分數(shù)據(jù)未能及時同步到從機,切換IP后還會引入數(shù)據(jù)不一致的問題,降低了系統(tǒng)的可用性
        Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜,為避免這一問題,運維人員在系統(tǒng)上線時必須確保有足夠的空間,這對資源造成了很大的浪費

        除了Redis,還有哪些緩存實現(xiàn)方式

        緩存可以分為分布式緩存和本地緩存
        Redis可以作為分布式緩存,當分布式部署時各個服務器之間可以保持緩存數(shù)據(jù)的一致性,但是需要保證其可用性,Redis可使用哨兵模式來保證其可用性

        Map可以用來做本地緩存,使用Map的key-value鍵值對來保存數(shù)據(jù),速度更快,其生命周期是和JVM一致的,當JVM銷毀時,本地緩存也隨之消失。當部署分布式時,每臺服務器上的緩存數(shù)據(jù)都是獨立存在的,不能保證相互之間的一致性

        Redis為什么這么快

        1、完全基于內(nèi)存,純內(nèi)存操作,非??焖?。
        2、數(shù)據(jù)結構簡單,數(shù)據(jù)操作也很簡單
        3、采用單線程,避免了不必要的上下文切換和競爭條件
        4、使用多路I/O復用模型,非阻塞IO
        5、Redis構建了自己的VM機制,省去了部分不必要的移動和請求時間

        Redis的數(shù)據(jù)類型

        數(shù)據(jù)類型可以存儲的值操作應用場景
        STRING字符串、整數(shù)或者浮點數(shù)對整個字符串或者字符串的其中一部分執(zhí)行操作;對整數(shù)和浮點數(shù)執(zhí)行自增或者自減操作做簡單的鍵值對緩存;短信驗證碼、配置信息
        LIST列表從兩端壓入或者彈出元素對單個或者多個元素進行修剪,只保留一個范圍內(nèi)的元素存儲一些列表型的數(shù)據(jù)結構,類似粉絲列表、文章的評論列表之類的數(shù)據(jù);省市區(qū)表、字典表、最新的...、消息隊列
        SET無序集合添加、獲取、移除單個元素;檢查一個元素是否存在于集合中交集、并集、差集的操作,比如交集,可以把兩個人的粉絲列表整一個交集;查找兩個人共同的好友
        HASH包含鍵值對的無序散列表添加、獲取、移除、單個鍵值對;獲取所有鍵值對;檢查某個鍵是否存在結構化的數(shù)據(jù),比如一個對象;商品詳情、個人信息詳情、新聞詳情
        ZSET有序集合添加、獲取、刪除元素;根據(jù)分值范圍或者成員來獲取元素;計算一個鍵的排名去重但可以排序,如獲取排名前幾的用戶;top 10

        Redis持久化

        持久化就是把內(nèi)存的數(shù)據(jù)寫到磁盤中,防止服務宕機了內(nèi)存數(shù)據(jù)丟失

        Redis提供兩種持久化機制RDB(默認)和AOF機制

        RDB:是Redis DataBase縮寫快照

        RDB是Redis默認的持久化方式。按照一定的時間將內(nèi)存的數(shù)據(jù)以快照的方式保存到硬盤中,對應產(chǎn)生的數(shù)據(jù)文件為dump.rdb。通過配置文件中的save參數(shù)來定義快照的周期

        優(yōu)點

        • 只有一個文件dump.rdb,方便持久化

        • 容災性好,一個文件可以保存到安全的磁盤

        • 性能最大化,fork子進程來完成寫操作,讓主進程繼續(xù)處理命令,所以是IO最大化。主進程不進行任何IO操作,保證了redis的高性能

        • 相對于數(shù)據(jù)集大時,比AOF的啟動效率更高

        缺點

        • 數(shù)據(jù)安全性低。RDB是隔一段時間進行持久化,如果持久化之間redis發(fā)生故障,會發(fā)生數(shù)據(jù)丟失。所以這種方式更適合數(shù)據(jù)要求不嚴謹?shù)臅r候

        AOF:持久化

        AOF(Append-Only file)是指所有的命令行記錄以redis命令請求協(xié)議的格式完全持久化存儲,保存為aof文件。當重啟Redis會重新從持久化的日志中恢復數(shù)據(jù)

        當兩種方式同時開啟時,數(shù)據(jù)恢復Redis時會優(yōu)先選擇AOF恢復

        優(yōu)點

        1. 數(shù)據(jù)安全,aof持久化可以配置appendfsync屬性,有always,每進行一次命令操作就記錄到aof文件中一次

        2. 通過append模式寫文件,即使中途服務器宕機,可以通過redis-check-aof工具解決數(shù)據(jù)一致性問題

        3. AOF的rewrite模式。AOF文件沒被rewritr之前(文件過大時會對命令進行合并重寫),可以刪除其中的某些命令

        缺點

        1. AOF文件比RDB文件大,且恢復速度慢

        2. 數(shù)據(jù)集大得時候,比rdb啟動效率低


        1. AOF文件比RDB更新頻率高,優(yōu)先使用AOF還原數(shù)據(jù)

        2. AOF比RDB更安全也更大

        3. RDB性能比AOF好

        4. 如果兩個都配了。優(yōu)先加載AOF


        Redis持久化數(shù)據(jù)和緩存怎么做擴容?

        • 如果Redis被當作緩存使用,使用一致性哈希實現(xiàn)動態(tài)擴容縮容

        • 如果Redis被當作一個持久化存儲使用,必須使用固定的keys-to-nodes映射關系,結點的數(shù)量一旦確定不能變化

        過期鍵的刪除策略

        Redis的過期鍵的刪除策略

        過期策略通常有以下三種

        • 定時過期:每個設置過期時間的key都需要創(chuàng)建一個定時器,到過期時間就會立即清除。該策略可以立即清除過期的數(shù)據(jù),對內(nèi)存很友好,但會占用大量的CPU資源去處理過期的數(shù)據(jù),從而影響緩存的響應時間和吞吐量

        • 惰性過期:只有當訪問一個key時,才會判斷key是否過期,過期則清楚。該策略可以最大化地節(jié)省CPU資源,卻對內(nèi)存不太友好。極端情況下可能出現(xiàn)大量的過期key沒有再次被訪問,從而不會被清除,占用大量內(nèi)存

        • 定期過期:每隔一定的時間,會掃描一定數(shù)量地數(shù)據(jù)庫地expires字典中一定數(shù)量地key,并清除其中已過期地key,該策略是前兩者地一個折中方案,通過調整定時掃描地時間間隔和每次掃描地限定耗時,可以在不同情況下是的CPU和內(nèi)存資源達到最優(yōu)的平衡

        Redis中同時使用了惰性過期和定期過期兩種過期策略

        Redis key的過期時間和永久有效分別怎么設置?

        EXPIRE和PERSIST命令

        內(nèi)存相關

        Mysql里有2000W數(shù)據(jù),redis中只存20W的數(shù)據(jù),如何保證redis中的數(shù)據(jù)都是熱點數(shù)據(jù)

        redis內(nèi)存數(shù)據(jù)集大小上升到一定大小的時候,就會施行數(shù)據(jù)淘汰策略

        Redis的內(nèi)存淘汰策略

        Redis的內(nèi)存淘汰策略是指在Redis的用于緩存的內(nèi)存不足時,怎么處理需要新寫入且需要申請額外的數(shù)據(jù)

        全局的鍵空間選擇性移除

        • noeviction:當內(nèi)存不足以容納新寫入數(shù)據(jù)時,新寫入數(shù)據(jù)會報錯

        • allkeys-lru:當內(nèi)存不足以容納新寫入數(shù)據(jù)時,在鍵空間中,移除最近最少使用的key(這個是最常使用的)

        • allkeys-random:當內(nèi)存不足以容納新寫入數(shù)據(jù)時,在鍵空間中,隨機移除某個key

        設置過期時間的鍵空間選擇性移除

        • volatile-lru:當內(nèi)存不足以容納新寫入數(shù)據(jù)時,在設置了過期時間的鍵空間中,移除最近最少使用的key

        • volatile-random:當內(nèi)存不足以容納新寫入數(shù)據(jù)時,在設置了過期時間的鍵空間中,隨機移除某個key

        • volatile-ttl:當內(nèi)存不足以容納新寫入數(shù)據(jù)時,在設置了過期時間的鍵空間中,有更早過期時間的key優(yōu)先移除

        Redis主要消耗什么物理資源

        內(nèi)存

        Redis的內(nèi)存用完了會發(fā)生什么?

        如果達到設置的上限,Redis的寫命令會返回錯誤信息(但是讀命令還可以正常返回)或者你可以配置內(nèi)存淘汰機制,當Redis達到內(nèi)存上限時會沖刷掉舊的內(nèi)容

        Redis如何做內(nèi)存優(yōu)化?

        散列表

        盡可能使用散列表(hash),散列表使用的內(nèi)存非常小

        縮減鍵值對象

        key長度:設計鍵規(guī)則時,在完整完整描述業(yè)務情況下,鍵值越短越好
        value長度:值對象縮減常見的方式就是將業(yè)務數(shù)據(jù)對象序列化二進制數(shù)組,序列化需要注意兩點
        (1)精簡對象信息,避免無用信息的存儲
        (2)序列化工具的選擇,選擇更為高效的序列化工具可以有效降低字節(jié)數(shù)組的大小

        共享對象池

        共享對象池指的是Redis內(nèi)部維護這[0-9999]的整數(shù)對象池。創(chuàng)建大量的整數(shù)類型redis對象存在內(nèi)存開銷,每個redis對象內(nèi)部結構至少占16字節(jié),甚至超過了整數(shù)自身空間消耗。所以redis內(nèi)部維護了一個[0-9999]的整數(shù)對象池,用于節(jié)省內(nèi)存

        設置內(nèi)存上限

        使用maxmemory參數(shù)限制最大可用內(nèi)存,當超出內(nèi)存上限時使用LRU等刪除策略釋放空間以及防止所用內(nèi)存超過服務器物理內(nèi)存

        配置內(nèi)存回收策略

        Redis所用內(nèi)存達到maxmemory上限時會觸發(fā)相應的溢出控制策略。具體策略受maxmemory-policy參數(shù)控制,Redis支持6種策略
        (1)noeviction:默認策略,不會刪除任何數(shù)據(jù),拒絕所有寫入操作并返回客戶端錯誤信息OOM,command not allowed when used memory,此時Redis只響應讀操作
        (2)volatile-lru:根據(jù)LRU算法刪除設置了超時屬性(expire)的鍵,直到騰出足夠空間為止。如果沒有可刪除的鍵對象,回退到noeviction策略。
        (3)allkeys-lru:根據(jù)LRU算法刪除鍵,不管數(shù)據(jù)有沒有設置超時屬性,直到騰出足夠空間為止
        (4)allkeys-random:隨機刪除所有鍵,直到騰出足夠空間為止
        (5)volatile-random:隨即刪除過期鍵,直到騰出足夠空間為止
        (6)volatile-ttl:根據(jù)鍵值對象的ttl屬性,刪除最近將要過期數(shù)據(jù)。如果沒有,回退到noeviction策略

        字符串優(yōu)化

        字符串對象是Redis內(nèi)部最常用的數(shù)據(jù)類型。所有的鍵都是字符串類 型,值對象數(shù)據(jù)除了整數(shù)之外都使用字符串存儲。在使用過程中應當盡量優(yōu)先使用整數(shù),比字符串類型更節(jié)省空間。并且要優(yōu)化字符串使用,避免預分配造成的內(nèi)存浪費。使用ziplist壓縮編碼優(yōu)化hash、list等結構,注重效率和空間的平衡,使用intset編碼優(yōu)化整數(shù)集合。使用ziplist編碼的hash結構降低小對象鏈規(guī)模。

        編碼優(yōu)化

        Redis對外提供了多種數(shù)據(jù)類型,但是Redis內(nèi)部對于不同類型的數(shù)據(jù)使用的內(nèi)部編碼不一樣。內(nèi)部編碼不同將直接影響數(shù)據(jù)的內(nèi)存占用和讀寫效率。

        控制鍵的數(shù)量

        當Redis存儲的數(shù)據(jù)越來越多,必然會存在大量的鍵,過多的鍵同樣會消耗大量的內(nèi)存

        Redis線程模型

        Redis基于Reactor模式開發(fā)了網(wǎng)絡事件處理器,這個處理器被稱為文件事件處理器(file event handler)。它的組成結構分為4部分:多個套接字、IO多路復用器、文件事件分派器、事件處理器。因為文件事件分派器隊列的消費是單線程的,所以Redis才叫單線程模型

        • 文件事件處理器使用I/O多路復用程序來同時監(jiān)聽多個套接字,并根據(jù)套接字目前執(zhí)行的任務來為套接字關聯(lián)不同的事件處理器

        • 當被監(jiān)聽的套接字準備好執(zhí)行連接應答(accept)、讀?。╮ead)、寫入(write)、關閉(close)等操作時,與操作對應的文件事件就會產(chǎn)生,這是文件事件處理器就會調用套接字之前關聯(lián)好的事件處理器來處理這些事件

        為啥 redis 單線程模型也能效率這么高?

        • 純內(nèi)存操作

        • 核心是基于非阻塞的 IO 多路復用機制

        • 單線程反而避免了多線程的頻繁上下文切換問題


        事務

        什么是事務?

        事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執(zhí)行。事務在執(zhí)行的過程中,不會被其他客戶端發(fā)送來的命令請求打斷

        事務是一個原子操作:事務中的命令要么全部被執(zhí)行,要么全部都不執(zhí)行

        Redis事務的概念

        Redis事務的本質是通過MULTI、EXEC、WATCH等一組命令的集合。事務支持一次執(zhí)行多個命令,一個事務中所有命令都會被序列化。在事務執(zhí)行過程,會按照串行化執(zhí)行隊列中的命令,其他客戶端提交的命令請求不會插入到事務執(zhí)行命令序列中

        Redis事務的三個階段

        1. 事務開始MULTI

        2. 命令入隊

        3. 事務執(zhí)行EXEC

        事務執(zhí)行過程中,如果服務端收到EXEC、DISCARD、WATCH、MULTI之外的請求,將會把請求放入隊列中排隊

        Redis事務相關命令

        Redis事務功能是通過MULTI、EXEC、DISCARD和WATCH四個原語實現(xiàn)的

        Redis會將一個事務中的所有命令序列化,然后按順序執(zhí)行

        1. redis不支持回滾,“Redis在事務失敗時不進行回滾,而是繼續(xù)執(zhí)行余下的命令”,所以Redis的內(nèi)部可以保持簡單且快速

        2. 如果在一個事務中的命令出現(xiàn)錯誤,那么所有的命令都不會執(zhí)行

        3. 如果在一個事務中出現(xiàn)運行錯誤,那么正確的命令會被執(zhí)行

        • WATCH命令是一個樂觀鎖,可以為Redis事務提供check-and-set(CAS)行為,可以監(jiān)控一個或多個鍵,一旦其中有一個鍵被修改(或刪除),之后的事務就不會被執(zhí)行,監(jiān)控一直持續(xù)到EXEC命令

        • MULTI命令用于開啟一個事務,它總是返回OK。MULTI執(zhí)行后,客戶端可以繼續(xù)向服務器發(fā)送多條命令,這些命令不會被立即執(zhí)行,而是放到一個隊列里,當EXEC命令執(zhí)行時,所有隊列中的命令才會被執(zhí)行

        • EXEC:執(zhí)行所有事務塊內(nèi)的命令,返回事務塊內(nèi)所有命令的返回值,按命令執(zhí)行的先后順序排列。當操作被打斷時,返回值null

        • 通過執(zhí)行DISCARD,客戶端可以清空事務隊列。并放棄執(zhí)行事務,并且客戶端會從事務狀態(tài)中退出

        • UNWATCH命令可以取消watch對所有key的監(jiān)控

        事務管理(ACID)概述

        原子性、一致性、隔離性、持久性

        Redis的事務總是具有ACID中的一致性和隔離性,其他特性是不支持的,當服務器運行在AOF持久化模式下,并且appendfsync選項的值未always時,事物也具有耐久性

        Redis事務支持隔離性嗎

        Redis是單進程程序,并且它保證在執(zhí)行事務時,不會對事務進行中斷,事務可以運行直到執(zhí)行完所有事務隊列中的命令為止。因此,Redis的事務總是帶有隔離性的

        Redis事務保證原子性嗎,支持回滾嗎

        Redis中,單條命令是原子性執(zhí)行的,但事務不保證原子性,且沒有回滾。事務中任意命令失敗,其余的命令仍會被執(zhí)行


        集群方案

        主從復制

        主機數(shù)據(jù)更新后根據(jù)配置和策略,自動同步到master/slave機制,Master以寫為主,Slave以讀為主

        主少從多、主寫從讀、讀寫分離、主寫同步復制到從

        一主二從

        搭建過程靜等后續(xù)吧

        哨兵模式

        哨兵的介紹

        sentinel,中文名是哨兵。哨兵是redis集群架構中非常重要的一個組件,主要有以下功能

        • 集群監(jiān)控:負責監(jiān)控redis master和slave進程是否正常工作

        • 消息通知:如果某個redis實例有故障,那么哨兵負責發(fā)送消息作為報警通知給管理員

        • 故障轉移:如果master node掛掉了,會自動轉移到slave node上

        • 配置中心:如果故障轉移發(fā)生了,通知client客戶端新的master地址

        哨兵用于實現(xiàn)redis集群的高可用,本身也是分布式的,作為一個哨兵集群去運行,互相協(xié)同去工作

        • 故障轉移時,判斷一個master node是否宕機了,需要大部分的哨兵都同意才行,涉及到了分布式選舉的問題

        • 即使部分哨兵節(jié)點掛掉了,哨兵集群還是能正常工作的,因為如果一個作為高可用機制重要組成部分的故障轉移系統(tǒng)本身是單節(jié)點的,就很扯淡

        哨兵的核心知識

        • 哨兵至少需要3個實例,來保證自己的健壯性

        • 哨兵+redis主從的部署架構,是不保證數(shù)據(jù)零丟失的,只能保證redis集群的高可用性

        • 對于哨兵+redis主從這種復雜的部署架構,盡量在測試環(huán)境和生產(chǎn)環(huán)境,都進行充足的測試和演練


        操作命令

        數(shù)據(jù)庫操作

        127.0.0.1:6379> select 3  #切換到3號數(shù)據(jù)庫,默認0號數(shù)據(jù)庫
        127.0.0.1:6379> dbsize  #查看數(shù)據(jù)庫大小
        127.0.0.1:6379> keys *  #查看所有的key
        127.0.0.1:6379> flushdb  #清空當前數(shù)據(jù)庫
        127.0.0.1:6379> flushall  #清空所有數(shù)據(jù)庫內(nèi)容
        127.0.0.1:6379> exists 'key'  #判斷某個key是否存在
        127.0.0.1:6379> move 'key' 1  #移除某個key,后面的1代表數(shù)據(jù)庫
        127.0.0.1:6379> expire 'key' 10  #設置某個key過期時間,10表示10秒
        127.0.0.1:6379> ttl 'key'  #查看某個key剩余時效
        127.0.0.1:6379> set 'key' 'value'  #set一個key
        127.0.0.1:6379> type 'key'  #查看當前key的類型

        數(shù)據(jù)類型及對應操作

        String

        127.0.0.1:6379> append 'key' 'value'  #在key對應的value上追加字符串
        127.0.0.1:6379> strlen 'key'  #獲取字符串長度
        127.0.0.1:6379> incr 'key'  #當前key加1
        127.0.0.1:6379> decr 'key'  #當前key減1
        127.0.0.1:6379> incrby 'key' 10  #當前key增加10
        127.0.0.1:6379> decrby 'key' 10  #當前key減少10
        127.0.0.1:6379> getrange 'key' 0 3  #截取當前字符串
        127.0.0.1:6379> getrange 'key' 0 -1  #獲取全部的字符串 和 get key是一樣的
        127.0.0.1:6379> setrange 'key' 1 xxx  #替換指定位置開始的字符串
        127.0.0.1:6379> setnx 'key' 30 xxx  #設置當前key的過期時間
        127.0.0.1:6379> setnx 'key' xxx  #不存在再設置(在分布式鎖中常使用)
        127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3  #同時設置多個值
        127.0.0.1:6379> mget k1 k2 k3  #同時獲取多個值

        127.0.0.1:6379> msetnx k1 v2 k4 v4  #msetnx 是一個原子性操作,要么一起成功,要么一起失敗

        List

        127.0.0.1:6379> lpush list one   #將一個值或者多個值,插入到列表的頭部(左)
        127.0.0.1:6379> rpush list one   #將一個值或者多個值,插入到列表的尾部(右)
        127.0.0.1:6379> lrange list 0 -1    #獲取list中的值
        127.0.0.1:6379> lrange list 0 1    #通過區(qū)間獲取list中具體的值
        127.0.0.1:6379> lpop list    #移除當前l(fā)ist中的第一個值
        127.0.0.1:6379> rpop list    #移除當前l(fā)ist中的最后一個值
        127.0.0.1:6379> lindex list 1   #通過下標獲取list的某一個值
        127.0.0.1:6379> llen list    #返回列表的長度
        127.0.0.1:6379> lrem list 1 one   #移除list集合中指定個數(shù)的value,精確匹配;移除列表中的1個one
        127.0.0.1:6379> lrem list 2 one   #移除list集合中指定個數(shù)的value,精確匹配;移除列表中的2個one
        127.0.0.1:6379> ltrim list 1 2    #通過下標截取指定的長度   改變list,list只剩下截取的元素
        127.0.0.1:6379> rpoplpush list targetlist #移除列表的最后一個元素并將其移動到另一個列表中
        127.0.0.1:6379> lset list 0 item #將列表中指定下標的值替換為另一個值
        127.0.0.1:6379> linsert list before "world" "other" #將某個具體的值插入列表中某個元素的前面
        127.0.0.1:6379> linsert list after "world" "other" #將某個具體的值插入列表中某個元素的后面

        Set

        127.0.0.1:6379> sadd myset "world" #set集合中添加元素
        127.0.0.1:6379> smembers myset  #查看set集合中的元素
        127.0.0.1:6379> sismembers myset hello  #查看set集合是否包含某個元素
        127.0.0.1:6379> scard myset  #獲取set集合中的內(nèi)容元素個數(shù)
        127.0.0.1:6379> srem myset hello #移除set集合中的某個元素
        127.0.0.1:6379> srandmember myset  #隨機抽選出一個元素
        127.0.0.1:6379> srandmember myset 2  #隨機抽選出指定個數(shù)的元素
        127.0.0.1:6379> spop myset  #隨機移除元素
        127.0.0.1:6379> smove myset targetset  #移動指定的元素到指定的集合
        127.0.0.1:6379> sdiff set1 set2  #獲取兩個集合的差集
        127.0.0.1:6379> sinter set1 set2  #獲取兩個集合的交集   共同好友可以這樣實現(xiàn)
        127.0.0.1:6379> sunion set1 set2  #獲取兩個集合的并集

        Hash

        127.0.0.1:6379> hset myhash key value  #set一個具體的key-value
        127.0.0.1:6379> hget myhash key  #獲取一個key對應的value
        127.0.0.1:6379> hmset myhash key value key1 value1  #set多個具體的key-value
        127.0.0.1:6379> hmget myhash key key1   #s獲取多個value
        127.0.0.1:6379> hgetall myhash    #獲取所有的key-value
        127.0.0.1:6379> hdel myhash key  #刪除hash指定的key,對應的value也不見了
        127.0.0.1:6379> hlen myhash  #獲取hash的長度
        127.0.0.1:6379> hexists myhash key #判斷hash中指定字段是否存在
        127.0.0.1:6379> hkeys myhash  #獲取所有的key
        127.0.0.1:6379> hvals myhash  #獲取所有的value
        127.0.0.1:6379> hincrby myhash key 1 #hash中指定key自增1
        127.0.0.1:6379> hdecrby myhash key 1 #hash中指定key自減1
        127.0.0.1:6379> hsetnx myhash key value #如果存在則可以設置
        #hash變更的數(shù)據(jù),hash更適合存儲對象

        Zset(有序集合)

        127.0.0.1:6379> zset myzset 1 one #添加一個值到zset
        127.0.0.1:6379> zset myzset 2 two 3 three  #添加多個值到zset
        127.0.0.1:6379> zrange myzset 0 -1  #獲取zset的所有值
        127.0.0.1:6379> zrangebyscore myzset -inf +inf  #獲取zset的所有值,從小到大排序
        127.0.0.1:6379> zrevrange myzset 0 -1  #獲取zset的所有值,從大到小
        127.0.0.1:6379> zrem myzset zzz  #移除有序集合中的指定元素
        127.0.0.1:6379> zcard myzset  #獲取有序集合中的個數(shù)
        127.0.0.1:6379> zcount myzset targer 1 3  #獲取指定區(qū)間的成員數(shù)量
        #消息設置權重   普通消息;重要消息;緊急消息

        Hyperloglog

        PFadd mykey a b c d e f g h i j #創(chuàng)建第一組元素
        PFcount mykey #統(tǒng)計mykey的元素的基數(shù)數(shù)量
        PFadd mykey2 i j z y x c v b #創(chuàng)建第二組元素
        PFcount mykey2 #統(tǒng)計第二組元素
        PFMERGE mykey3 mykey mykey2  #合并兩組 mykey mykey2 => mykey3 并集
        PFCOUNT mykey3 #看并集的數(shù)量


        #如果允許容錯,那么一定可以使用Hyperloglog,如果不允許容錯,就使用set

        事務

        事務的原則:ACID:原子性、一致性、隔離性、持久性

        Redis單條命令保存原子性,但是事務不保證原子性

        Redis事務的本質:一組命令的事務

        開啟事務  multi
        命令入隊  
        執(zhí)行事務 exec

        127.0.0.1:6379> multi  #開啟事務
        OK
        127.0.0.1:6379> set k1 v1
        QUEUED
        127.0.0.1:6379> set k2 v2
        QUEUED
        127.0.0.1:6379> exec  #執(zhí)行事務
        1) OK
        2) OK
        127.0.0.1:6379>


        #放棄事務 事務中的命令都不會被執(zhí)行
        127.0.0.1:6379> discard


        #異常
        ##編譯型異常 命令有錯,事務中所有命令都不會執(zhí)行
        ##運行時異常 如果事務隊列中存在語法性,那么執(zhí)行命令時,其他命令是可以正常執(zhí)行的,錯誤命令會拋出異常

        Redis事務沒有隔離級別的概念

        所有的命令在事務中,并沒有直接被執(zhí)行,只有發(fā)起執(zhí)行命令的時候才會執(zhí)行

        !?。。?!Redis的watch可以實現(xiàn)樂觀鎖的操作

        watch money  #監(jiān)視money
        multi        #開啟事務
        incrby money #命令入隊 money+1
        decrby money #命令入隊 money-1
        exec         #比對監(jiān)視的值是否發(fā)生了變化,如果沒有變化,那么可以執(zhí)行成功,如果有變化就執(zhí)行失敗

        Redis.conf詳解

        1、配置文件unit單位第一大小寫不敏感
        2、includes可以包含多個配置文件的信息
        3、network
        bind 127.0.0.1  #綁定的ip
        protected-mode yes #保護模式
        port 6379 #端口設置
        4、daemonize yes  #以守護進程的方式運行,默認是no,我們需要自己開啟為yes
        5、pidfile /var/run/redis_6379.pid  #如果以后臺的方式運行,我們就需要指定一個pid文件
        6、loglevel notice #日志級別
        7、log file“” #日志的文件路徑
        8、databases 16 # 數(shù)據(jù)庫的數(shù)量,默認是16個數(shù)據(jù)庫
        9、always-show-logo yes #是否總是顯示logo
        10、持久化,在規(guī)定的時間內(nèi),執(zhí)行多少次操作則會持久化到 .rdb .aof
        redis是內(nèi)存數(shù)據(jù)庫,如果沒有持久化,那么數(shù)據(jù)斷電即失
        save 900 1   # 如果 900s 內(nèi),至少有 1 個 可以進行了修改,我們就進行持久化操作
        save 300 10 # 如果 300s 內(nèi),至少有 10 個 可以進行了修改,我們就進行持久化操作
        save 60 1000 # 如果 60s 內(nèi),至少有 1000 個 可以進行了修改,我們就進行持久化操作
        11、stop-writes-on-bgsave-error yes #如果持久化出錯,redis是否正常工作
        12、rdbcompression yes  #是否壓縮rdb文件,需要消耗一些cpu資源
        13、rdbchecksun yes #保存rdb文件時,進行錯誤的校驗
        14、dir ./ #rdb 文件保存的目錄#

        ########限制CLIENTS#########
        15、maxclients 1000 # 設置能連接上redis的最大客戶端的數(shù)量
        16、maxmemory <bytes> # redis 配置最大的內(nèi)存容量
        17、maxmemory-policy noeviction # 內(nèi)存到達上之后的處理策略
        TODO 需要補充策略

        ########APPEND ONLY 模式 AOF配置#########
        18、appendonly no #默認是不開啟aof模式的,默認是使用rdb方式持久化的,在大部分的情況下,rdb完全夠用
        19、appendfilename "appendonly.aof" #持久化文件的名字
        20、 appendfsync always #每次修改都會sync , 消耗性能
        appendfsync everysec #每秒執(zhí)行一次sync,可能會丟失這1s的數(shù)據(jù)
        appendfsync no #不執(zhí)行sync,這個時候操作系統(tǒng)自己同步數(shù)據(jù),速度最快

        觸發(fā)持久化機制(RDB)

        1、save的規(guī)則滿足的情況下,會自動觸發(fā)rdb規(guī)則
        2、執(zhí)行flushall命令,也會觸發(fā)我們的rdb規(guī)則
        3、退出redis,也會產(chǎn)生rdb文件

        ####如果要恢復rdb文件,只需要將rdb文件放在redis啟動目錄就可以,redis啟動的時候會自動檢查dump.rdb,恢復其中的數(shù)據(jù)
        ####優(yōu)點:1、適合大規(guī)模的數(shù)據(jù)恢復
        #### 2、對數(shù)據(jù)的完整性要求不高
        ####缺點:1、需要一定的時間間隔進程操作,如果redis意外宕機,這個最后一次的操作將會丟失

        AOF(Append Only File)(默認不開啟,需手動開啟,重啟redis生效)

        將我們所有的命令都記錄下來,history,恢復的時候就把這個文件全部再執(zhí)行一遍

        1、AOF在大數(shù)據(jù)的情況下效率很低
        2、AOF被破壞的話,redis將不能啟動;可以使用 redis-check-aof --fix 進行修復


        本文為學習筆記,參考多篇文章及教學視頻,如有侵權,請后臺聯(lián)系

        瀏覽 48
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 天天噜天天操 | 黄色短篇小说在线观看 | 中国一级黄片操逼片 | 国产拔擦拔擦8ⅹ8x更快乐 | 性欧美XXX内谢 |