Redis 介绍
1、簡介
Redis 是一款開源的,基于 BSD 許可的,高級鍵值 (key-value) 緩存 (cache) 和存儲 (store) 系統。由于 Redis 的鍵包括 string,hash,list,set,sorted set,bitmap 和 hyperloglog,所以常常被稱為數據結構服務器。
為了滿足高性能,Redis 采用內存 (in-memory) 數據集 (dataset)。根據你的使用場景,你可以通過每隔一段時間轉儲數據集到磁盤,或者追加每條命令到日志來持久化。持久化也可以被禁用,如果你只是需要一個功能豐富,網絡化的內存緩存。
Redis 還支持主從異步復制,非??斓姆亲枞醮瓮健⒕W絡斷開時自動重連局部重同步。
Redis特點:1、Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用。
2、Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,sorted set,hash等數據結構的存儲。
3、Redis支持數據的備份,即master-slave模式的數據備份。
Redis優勢:
1、性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
2、豐富的數據類型 – Redis支持二進制案例的 String, List, Hash, Set 及 Sorted Set 數據類型操作。
3、原子 – Redis的所有操作都是原子性的,同時Redis還支持對幾個操作全并后的原子性執行。
4、豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性 2、多數據類型
- String
- List
- Set
- Hash
- Sorted Set
3、持久化
redis支持兩種持久化方式,一種是 RDB(快照)也是默認方式,另一種是Append-only file(aof)的方式。
3.1 快照RDB
快照是默認的持久化方式。這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名為dump.rdb。可以通過配置設置自動做快照持久化的方式。我們可以配置redis在n秒內如果超過m個key被修改就自動做快照。也可以命令行的方式讓redis進行snapshotting。
快照生成過程大致如下:redis調用fork出父子進程,父進程繼續處理client請求,子進程負責將內存內容寫入到臨時文件。由于os的寫時復制機制(copy on write)父子進程會共享相同的物理頁面,當父進程處理寫請求時os會為父進程要修改的頁面創建副本,而不是寫共享的頁面。所以子進程的地址空間內的數據是fork時刻整個數據庫的一個快照;當子進程將快照寫入臨時文件完畢后,用臨時文件替換原來的快照文件,然后子進程退出。 快照(snapshotting)不足之處在于兩次快照操作之間是有時間間隔的,一旦數據庫出現問題,那么快照文件中保存的數據并不是全新的,從上次快照文件生成到Redis停機這段時間的數據全部丟掉了。 3.2 aof方式 比上面所說的快照方式有更好的持久化性,是由于在使用aof持久化方式時,redis會將每一個收到的寫命令都通過write函數追加到文件中(默認是 appendonly.aof)。當redis重啟時會通過重新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。 可以通過配置文件告訴redis我們想要通過fsync函數強制os寫入到磁盤的時機。有三種方式如下(默認是:每秒fsync一次): 1、appendonly yes //啟用aof持久化方式
2、appendfsync always //每次收到寫命令就立即強制寫入磁盤,最慢的,但是保證完全的持久化,不推薦使用
3、appendfsync everysec //每秒鐘強制寫入磁盤一次,在性能和持久化方面做了很好的折中,推薦
4、appendfsync no //完全依賴os,性能最好,持久化沒保證
aof方式的持久化也還是有可能會丟失部分修改,因為os會在內核中緩存 write做的修改,所以可能不是立即寫到磁盤上。另外aof 的方式可能會導致持久化文件會變的越來越大。為了壓縮aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis將使用與快照類似的方式將內存中的數據以命令的方式保存到臨時文件中,最后替換原來的文件。 bgrewriteaof命令執行過程如下: redis調用fork出父子兩個進程,子進程根據內存中的數據庫快照,往臨時文件中寫入重建數據庫狀態的命令;
父進程繼續處理client請求,除了把寫命令寫入到原來的aof文件中。同時把收到的寫命令緩存起來。這樣就能保證如果子進程重寫失敗的話并不會出問題;
當子進程把快照內容寫入以命令方式寫到臨時文件中后,子進程發信號通知父進程。然后父進程把緩存的寫命令也寫入到臨時文件;
現在父進程可以使用臨時文件替換老的aof文件,并重命名,后面收到的寫命令也開始往新的aof文件中追加。
4、內存管理
4.1?Redis對象
所有的Redis對象都被封裝在RedisObject這個結構體當中,如下:
typedef struct redisObject {unsigned type, // 4字節,數據類型(String,List,Set,Hash,Sorted Set)unsigned encoding, // 4字節,編碼方式unsigned lru, // 24字節int refcount, // 對象引用計數void *ptr // 數據具體存儲的指向 } robj;Redis 內部使用一個 redisObject 對象來表示所有的 key 和 value,type 代表一個 value 對象具體是何種數據類型,encoding 是不同數據類型在 redis 內部的存儲方式,比如:type=string 代表 value 存儲的是一個普通字符串,那么對應的 encoding 可以是 raw 或者是 int,如果是 int 則代表實際 redis 內部是按數值型類存儲和表示這個字符串的。
4.2 內存淘汰策略
Redis提供了下面幾種淘汰策略供用戶選擇,其中默認的策略為noeviction策略:
- noeviction:當內存使用達到閾值的時候,所有引起申請內存的命令會報錯。
- allkeys-lru:在主鍵空間中,優先移除最近未使用的key。
- volatile-lru:在設置了過期時間的鍵空間中,優先移除最近未使用的key。
- allkeys-random:在主鍵空間中,隨機移除某個key。
- volatile-random:在設置了過期時間的鍵空間中,隨機移除某個key。
- volatile-ttl:在設置了過期時間的鍵空間中,具有更早過期時間的key優先移除
5、主從同步
Redis的主從復制功能非常強大,一個master可以擁有多個slave,而一個slave又可以擁有多個slave,如此下去,形成了強大的多級服務器集群架構。
Redis主從復制的一些特點:
1.master可以有多個slave
2.除了多個slave連到相同的master外,slave也可以連接其他slave形成圖狀結構
3.主從復制不會阻塞master。也就是說當一個或多個slave與master進行初次同步數據時,master可以繼續處理client發來的請求。相反slave在初次同步數據時則會阻塞不能處理client的請求。
4.主從復制可以用來提高系統的可伸縮性,我們可以用多個slave 專門用于client的讀請求,比如sort操作可以使用slave來處理。也可以用來做簡單的數據冗余
5.可以在master禁用數據持久化,只需要注釋掉master 配置文件中的所有save配置,然后只在slave上配置數據持久化。
Redis主從復制的過程:
當設置好slave服務器后,slave會建立和master的連接,然后發送sync命令。無論是第一次同步建立的連接還是連接斷開后的重新連接,master都會啟動一個后臺進程,將數據庫快照保存到文件中,同時master主進程會開始收集新的寫命令并緩存起來。后臺進程完成寫文件后,master就發送文件給slave,slave將文件保存到磁盤上,然后加載到內存恢復數據庫快照到slave上。接著master就會把緩存的命令轉發給slave。而且后續master收到的寫命令都會通過開始建立的連接發送給slave。從master到slave的同步數據的命令和從 client發送的命令使用相同的協議格式。當master和slave的連接斷開時slave可以自動重新建立連接。如果master同時收到多 slave發來的同步連接命令,只會使用啟動一個進程來寫數據庫鏡像,然后發送給所有slave。
redis的主從復制策略是通過其持久化的rdb文件來實現的,其過程是先dump出rdb文件,將rdb文件全量傳輸給slave,然后再將dump后的操作實時同步到slave中。
1、Slave端在配置文件中添加了slaveof指令,于是Slave啟動時讀取配置文件,初始狀態為REDIS_REPL_CONNECT;
2、Slave端在定時任務serverCron中連接Master,發送sync命令,然后阻塞等待master發送回其內存快照文件(最新版的Redis已經不需要讓Slave阻塞);
3、Master端收到sync命令簡單判斷是否有正在進行的內存快照子進程,沒有則立即開始內存快照,有則等待其結束,當快照完成后會將該文件發送給Slave端;
4、Slave端接收Master發來的內存快照文件,保存到本地,待接收完成后,清空內存表,重新讀取Master發來的內存快照文件,重建整個內存表數據結構,并最終狀態置位為 REDIS_REPL_CONNECTED狀態,Slave狀態機流轉完成;
5、Master端在發送快照文件過程中,接收的任何會改變數據集的命令都會暫時先保存在Slave網絡連接的發送緩存隊列里(list數據結構),待快照完成后,依次發給Slave,之后收到的命令相同處理,并將狀態置位為 REDIS_REPL_ONLINE。
6、事物機制:
Redis事務通常會使用MULTI,EXEC,WATCH等命令來完成,redis的事務不支持回滾,事務執行時會阻塞其它客戶端的請求執行。Redis事務從開始到結束通常會通過三個階段:1、事務開始 2、命令入隊 3、命令執行。 與實務相關的狀態標識flag,用于標識當前客戶端的事物狀態,如下: #define REDIS_MULTI (1<<3) #define REDIS_DIRTY_EXEC (1<<12) #define REDIS_DIRTY_CAS (1<<5)
7、應用場景
1、session會話共享緩存
2、數據緩存
3、隊列:1)Redis自帶的PUB/SUB機制,即發布-訂閱模式。2)Redis的PUSH/POP機制,利用的Redis的列表(lists)數據結構。比較好的使用模式是,生產者lpush消息,消費者brpop消息,并設定超時時間,可以減少redis的壓力。
?
Redis 命令參考Doc
轉載于:https://www.cnblogs.com/kingsonfu/p/10407413.html
總結
- 上一篇: 公司电脑用域账号访问团队文件夹
- 下一篇: 关系型数据库、非关系型数据库