文章目錄
- 一、NoSQL
- 二、Redis安裝
- 三、Redis基礎命令
- 1. 查看Redis服務是否正常 ping
- 2. 查看當前數據庫中 key 的數目 dbsize
- 3. Redis的默認庫
- 4. 切換庫命令 select
- 5. 刪除當前庫的數據 flushdb
- 6. 刪除所有庫的數據 flushall
- 7. 退出當前 redis 連接 exit/quit
- 8. 關閉redis服務 shutdown
- 四、Redis的Key操作
- 1. 查看匹配的key keys
- 2. 判斷 key 是否存在 exists
- 3. 設置 key 的生存時間 expire
- 4. 查看key的剩餘生存時間 ttl
- 5. 查看 key 所存儲值的數據類型 type
- 6. 刪除存在的key del
- 五、字符串類型
- 1. 基本命令 (set/get/incr/decr/append)
- 2. key 所儲存的字符串值的長度 strlen
- 3. 截取字符串 getrange
- 4. 替換 setrange
- 5. 批量設置 mset
- 6. 批量取值 mget
- 六、哈希類型 hash
- 1. 設定值 hset
- 2. 獲取值 hget
- 3. 批量設置域 hmset
- 4. 批量獲取域 hmget
- 5. 獲取所有域和值 hgetall
- 6. 刪除一個或多個域 hdel
- 7. 查看所有的域的field hkeys
- 8. 查看所有域的值 hvals
- 9. 查看給定域 field 是否存在 hexists
- 七、列表 list
- 1. 插入多個值 lpush
- 2. 獲取多個值 rpush
- 3. 獲取區間內的值 lrange
- 4. 獲取指定下標的元素 lindex
- 5. 獲取列表的長度 llen
- 6. 刪除元素 lrem
- 7. 根據下標修改值 lset
- 8. 插入 linsert
- 八、集合類型 set
- 1. 增 sadd
- 2. 查 smembers
- 3. 判斷是否存在 sismember
- 4. 獲取個數 scard
- 5. 刪除 srem
- 6. 隨機返回一個元素 srandmember
- 7. 隨機刪除一個元素 spop
- 九、有序集合類型 zset (sorted set)
- 1. 添加 zadd
- 2. 區間查詢,升序 zrange
- 3. 區間查詢,降序 zrevrange
- 4. 刪除 zrem
- 5. 獲取成員個數 zcard
- 6. 根據分數範圍獲取元素(升序) zrangebyscore
- 7. 根據分數範圍獲取元素(降序) zrevrangebyscore
- 8. 根據分數範圍獲取元素數量 zcount
- 十、事務
- 十一、持久化
- 十二、主從複製
- 十三、其它設置
- 十四、Jedis
一、NoSQL
NoSQL = Not Only SQL(不僅僅是 SQL) ,也解釋爲 non-relational(非關係型數據庫)。在 NoSQL 數據庫中數據之間是無聯繫的,無關係的。數據的結構是鬆散的,可變的。
1. MySQL的瓶頸
- 無法應對每秒上萬次的讀寫請求, 無法處理大量集中的高併發操作。關係型數據的是 IO 密集的應用。 硬盤 IO 也變爲性能瓶頸
- 無法簡單地通過增加硬件、服務節點來提高系統性能。數據整個存儲在一個數據庫中的。多個服務器沒有很好的解決辦法,來複制這些數據。
- 關係型數據庫大多是收費的,對硬件的要求較高。軟件和硬件的成本花費比重較大。
2. NoSQL的優勢
- 大數據量,高性能
NoSQL 數據庫都具有非常高的讀寫性能,尤其在大數據量下,同樣表現優秀。這得益於它的無關係性,數據庫的結構簡單。 關係型數據庫(例如 MySQL)使用查詢緩存。這種查詢緩存在更新數據後,緩存就是失效了。在頻繁的數據讀寫交互應用中。緩存的性能不高。NoSQL 的緩存性能要高的多。 - 靈活的數據模型
NoSQL 無需事先爲要存儲的數據建立字段,隨時可以存儲自定義的數據格式。而在關係數據庫裏,增刪字段是一件非常麻煩的事情。如果是非常大數據量的表,增加字段簡直就是一個噩夢。 尤其在快速變化的市場環境中,用戶的需求總是在不斷變化的。 - 高可用
NoSQL 在不太影響性能的情況,就可以方便的實現高可用的架構。NoSQL 能很好的解決關係型數據庫擴展性差的問題。 彌補了關係數據(比如 MySQL)在某些方面的不足,在某些方面能極大的節省開發成本和維護成本。MySQL 和 NoSQL 都有各自的特點和使用的應用場景,兩者結合使用。讓關係數據庫關注在關係上, NoSQL 關注在存儲上。 - 低成本
這是大多數分佈式數據庫共有的特點,因爲主要都是開源軟件,沒有昂貴的 License 成本
3. NoSQL 的劣勢
- 不支持標準的 SQL,沒有公認的 NoSQL 標準
- 沒有關係型數據庫的約束,大多數也沒有索引的概念
- 沒有事務,不能依靠事務實現 ACID
- 沒有豐富的數據類型(數值,日期,字符,二進制,大文本等)
更詳細的介紹請戳這裏(https://www.cnblogs.com/xrq730/p/11039384.html)
二、Redis安裝
Remote Dictionary Server(Redis)是一個開源的使用 C 語言編寫、支持網絡、可基於內存亦可持久化的 Key-Value 數據庫。Key 字符類型, 其值(value)可以是字符串(String),哈希(Map),列表(list),集合(sets) 和有序集合(sorted sets)等類型, 每種數據類型有自己的專屬命令。 所以它通常也被稱爲數據結構服務器。
1. 解壓
- 上傳 redis-4.0.13.tar.gz 到 linux 系統。使用 Xftp 工具
- 解壓 redis-4.0.13.tar.gz 到/usr/local 目錄
2. 編譯Redis源文件
Redis 是使用 c 語言編寫的。 使用源文件安裝方式,需要編譯 c 源文件, 會使用 gcc 編譯器。gcc 是 GNU compiler collection 的縮寫,它是 Linux 下一個編譯器集合(相當於 javac ), 是c 或 c++程序的編譯器。
- 使用yum進行安裝gcc 。
執行命令:yum -y install gcc
- 編譯 redis 源文件
在解壓後的 Redis 目錄下執行(cd /usr/local/redis-4.0.13) make 命令:
如果 make 命令執行過程中出現錯誤:error: jemalloc/jemalloc.h: No such file or directorymake
解決方式執行下面的命令:make MALLOC=libc
- 編譯成功的標誌
- 查看make的編譯結果
查看Redis的src目錄:
3. 啓動和關閉Redis服務
- 後臺啓動Redis:
在src目錄下執行:./redis-server redis.conf配置文件路徑 &
./redis-server ../redis.conf &
此時 ctrl + c 關閉窗口後,查看redis進程,依然存在。 - 關閉 Redis
使用 redis 客戶端關閉,向服務器發出關閉命令
切換到 redis-4.0.13/src/ 目錄,執行:
推薦使用這種方式, redis 先完成數據操作,然後再關閉。./redis-cli shutdown
4. Redis客戶端
(1)命令行客戶端
在 redis 安裝目錄/src下執行:
命令 | 說明 | 示例 |
---|---|---|
./redis-cli -h IP地址 -p 端口號 | 指定 IP 和端口連接 redis | ./redis-cli -h 127.0.0.1 -p 6379 |
./redis-cli | 直接連接 redis (默認 ip127.0.0.1,端口 6379) | ./redis-cli |
(2)遠程連接Redis
連接Linux的Reids之前需要修改Redis服務器的配置信息。 Redis服務器有安全保護措施,默認只有本機(安裝Redis的那臺機器)能夠訪問。
修改redis主目錄下的redis.conf
配置文件:(vim中使用 / 進行搜索)
- bind ip 綁定ip此行註釋
- protected-mode yes 保護模式改爲 no
注意:修改完之後要重啓Redis服務,並且記得關閉防火牆
三、Redis基礎命令
1. 查看Redis服務是否正常 ping
返回PONG,表示 redis 服務運行正常
2. 查看當前數據庫中 key 的數目 dbsize
3. Redis的默認庫
Redis 默認使用 16 個庫, 從 0 到 15。 對數據庫個數的修改,在 redis.conf 文件中修改databases 16
默認打開的是第0個數據庫
4. 切換庫命令 select
使用其他數據庫, 命令是 select index
5. 刪除當前庫的數據 flushdb
6. 刪除所有庫的數據 flushall
7. 退出當前 redis 連接 exit/quit
8. 關閉redis服務 shutdown
四、Redis的Key操作
1. 查看匹配的key keys
語法: keys pattern
作用:查找當前庫中所有符合模式 pattern 的 key. pattern 可以使用通配符。
通配符:
- *:表示 0 - 多個字符,例如: keys * 查詢所有的 key。
- ?:表示單個字符,例如: wo?d , 匹配 word , wood
2. 判斷 key 是否存在 exists
語法: exists key [key…]
作用:判斷 key 是否存在
返回值:整數,存在 key 返回 1,其他返回 0。使用多個 key,返回存在的 key 的數量。
3. 設置 key 的生存時間 expire
語法: expire key seconds
作用:設置 key 的生存時間, 超過時間, key 自動刪除。單位是秒。
返回值:設置成功返回數字 1,其他情況是 0 。
4. 查看key的剩餘生存時間 ttl
語法: ttl key
作用:以秒爲單位,返回 key 的剩餘生存時間(ttl: time to live)
返回值:
- -1 :沒有設置 key 的生存時間, key 永不過期。
- -2: key 不存在
- 數字: key 的剩餘時間,秒爲單位
5. 查看 key 所存儲值的數據類型 type
語法: type key
作用:查看 key 所存儲值的數據類型
返回值:字符串表示的數據類型
- none (key 不存在)
- string (字符串)
- hash (哈希表)
- list (列表)
- set (集合)
- zset (有序集)
6. 刪除存在的key del
語法: del key [key…]
作用:刪除存在的 key,不存在的 key 忽略。
返回值:數字,刪除的 key 的數量。
五、字符串類型
字符串類型(string)是 Redis 中最基本的數據類型,它能存儲任何形式的字符串,包括二進制數據,序列化後的數據, JSON 格式數據。
1. 基本命令 (set/get/incr/decr/append)
命令 | 說明 | 返回值 |
---|---|---|
set key value | 將字符串值 value 設置到 key 中 向已經存在的 key 設置新的 value,會覆蓋原來的值 |
OK |
get key | 獲取 key 中設置的字符串值 | 返回value值 |
incr key | 將 key 中儲存的數字值加 1(只能對數字類型的數據操作) 如果 key 不存在,則 key 的值先被初始化爲 0 再執行incr 操作 |
返回修改後的值 |
decr key | 將 key 中儲存的數字值減1,其它與incr相同 | 返回修改後的值 |
append key value | 如果 key 存在,則將 value 追加到 key 原來舊值的末尾 如果 key 不存在,則將 key 設置值爲 value |
追加字符串之後的總長度 |
2. key 所儲存的字符串值的長度 strlen
語法: strlen key
說明: 返回 key 所儲存的字符串值的長度
返回值:
- 如果key存在,返回字符串值的長度
- key不存在,返回
3. 截取字符串 getrange
語法: getrange key start end
作用: 獲取 key 中字符串值從 start 開始到 end 結束的子字符串,包括 start 和 end,負數表示從字符串的末尾開始, -1 表示最後一個字符,超出字符串範圍的截取, 獲取合理的子串
返回值: 截取的子字符串。
使用的字符串 key: school, value: bjpowernode
4. 替換 setrange
語法: setrange key offset value
說明: 用 value 覆蓋(替換) key 的存儲的值,key中的值從 offset 開始的value長度的字符串被替換,不存在的 key 當做空白字符串。
返回值: 修改後的字符串的長度
5. 批量設置 mset
語法: mset key value [key value…]
說明: 同時設置一個或多個 key-value 對
返回值: OK
6. 批量取值 mget
語法: mget key [key …]
作用: 獲取所有(一個或多個)給定 key 的值
返回值: 包含所有 key 的列表,不存在返回nil
六、哈希類型 hash
redis hash 是一個 string 類型的 field 和 value 的映射表, hash 特別適合用於存儲對象。
1. 設定值 hset
語法: hset hash表的key field value
作用: 將哈希表 key 中的域 field 的值設爲 value, 如果 key 不存在, 則新建 hash 表,執行賦值,如果有 field,則覆蓋值。
返回值:
- 如果 field 是 hash 表中新 field,且設置值成功,返回 1
- 如果 field 已經存在,新值覆蓋舊值,返回 0
2. 獲取值 hget
語法: hget key field
作用: 獲取哈希表 key 中給定域 field 的值
返回值: field 域的值,如果 key 不存在或者 field 不存在返回 nil
3. 批量設置域 hmset
語法: hmset key field value [field value…]
說明: 同時將多個 field-value (域-值)設置到哈希表 key 中,此命令會覆蓋已經存在的 field,hash 表 key 不存在,創建空的 hash 表,執行 hmset.
返回值:設置成功返回 ok,如果失敗返回一個錯誤
4. 批量獲取域 hmget
語法: hmget key field [field…]
作用:獲取哈希表 key 中一個或多個給定域的值
返回值:返回和 field 順序對應的值,如果 field 不存在,返回 nil
5. 獲取所有域和值 hgetall
語法: hgetall key
作用: 獲取哈希表 key 中所有的域和值
返回值:以列表形式返回 hash 中域和域的值, key 不存在,返回空 hash
6. 刪除一個或多個域 hdel
語法: hdel key field [field…]
作用: 刪除哈希表 key 中的一個或多個指定域 field,不存在 field 直接忽略
返回值:成功刪除的 field 的數量
7. 查看所有的域的field hkeys
語法: hkeys key
作用:查看哈希表 key 中的所有 field 域
返回值:包含所有 field 的列表, key 不存在返回空列表
8. 查看所有域的值 hvals
語法: hvals key
作用: 返回哈希表中所有域的值
返回值:包含哈希表所有域值的列表, key 不存在返回空列表
9. 查看給定域 field 是否存在 hexists
語法: hexists key field
作用: 查看哈希表 key 中,給定域 field 是否存在
返回值:如果 field 存在,返回 1,其他返回 0
七、列表 list
Redis 列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素導列表的頭部(左邊)或者尾部(右邊)
1. 插入多個值 lpush
語法: lpush key value [value…]
作用: 將一個或多個值 value 插入到列表 key 的表頭(最左邊),從左邊開始加入值, 從左到右的順序依次插入到表頭
返回值: 數字, 新列表的長度
2. 獲取多個值 rpush
語法: rpush key value [value…]
作用: 將一個或多個值 value 插入到列表 key 的表尾(最右邊), 各個 value 值按從左到右的順序依次插入到表尾
返回值:數字,新列表的長度
3. 獲取區間內的值 lrange
語法: lrange key start stop
作用: 獲取列表 key 中指定區間內的元素, 0 表示列表的第一個元素,以 1 表示列表的第二個元素; start , stop 是列表的下標值,也可以負數的下標, -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。 start , stop 超出列表的範圍不會出現錯誤。
返回值: 指定區間的列表
4. 獲取指定下標的元素 lindex
語法: lindex key index
作用: 獲取列表 key 中下標爲指定 index 的元素, 列表元素不刪除, 只是查詢。 0 表示列表的第一個元素,以 1 表示列表的第二個元素; start , stop 是列表的下標值,也可以負數的下標, -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。
返回值:指定下標的元素; index 不在列表範圍,返回 nil
5. 獲取列表的長度 llen
語法: llen key
作用: 獲取列表 key 的長度
返回值: 數值,列表的長度; key 不存在返回 0
6. 刪除元素 lrem
語法: lrem key count value
作用: 根據參數 count 的值,移除列表中與參數 value 相等的元素, count >0 , 從列表的左側向右開始移除; count < 0 從列表的尾部開始移除; count = 0 移除表中所有與 value 相等的值。
返回值: 數值,移除的元素個數
7. 根據下標修改值 lset
語法: lset key index value
作用: 將列表 key 下標爲 index 的元素的值設置爲 value。
返回值:設置成功返回 ok;key 不存在或者 index 超出範圍返回錯誤信息
8. 插入 linsert
語法: linsert key BEFORE|AFTER pivot value
作用: 將值 value 插入到列表 key 當中位於值 pivot 之前或之後的位置。 key 不存在, pivot不在列表中,不執行任何操作。
返回值: 命令執行成功,返回新列表的長度。沒有找到 pivot 返回 -1, key 不存在返回 0。
八、集合類型 set
redis 的 Set 是 string 類型的無序集合,集合成員是唯一的,即集合中不能出現重複的數據
1. 增 sadd
語法: sadd key member [member…]
作用: 將一個或多個 member 元素加入到集合 key 當中,已經存在於集合的 member 元素將被忽略, 不會再加入。
返回值:加入到集合的新元素的個數。不包括被忽略的元素。
2. 查 smembers
語法: smembers key
作用: 獲取集合 key 中的所有成員元素,不存在的 key 視爲空集合
3. 判斷是否存在 sismember
語法: sismember key member
作用: 判斷 member 元素是否是集合 key 的成員
返回值: member 是集合成員返回 1,其他返回 0 。
4. 獲取個數 scard
語法: scard key
作用: 獲取集合裏面的元素個數
返回值:數字, key 的元素個數。其他情況返回 0 。
5. 刪除 srem
語法: srem key member [member…]
作用: 刪除集合 key 中的一個或多個 member 元素,不存在的元素被忽略。
返回值:數字,成功刪除的元素個數, 不包括被忽略的元素。
6. 隨機返回一個元素 srandmember
語法: srandmember key [count]
作用:只提供 key,隨機返回集合中一個元素,元素不刪除,依然在集合中;提供了 count 時, count 正數, 返回包含 count 個數元素集合,集合元素各不相同。 count 是負數,返回一個 count 絕對值的長度的集合,集合中元素可能會重複多次。
返回值:一個元素;多個元素的集合
7. 隨機刪除一個元素 spop
語法: spop key [count]
作用: 隨機從集合中刪除一個元素, count 是刪除的元素個數。
返回值:被刪除的元素, key 不存在或空集合返回 nil
九、有序集合類型 zset (sorted set)
redis 有序集合zset和集合set一樣也是string類型元素的集合,且不允許重複的成員。不同的是 zset 的每個元素都會關聯一個分數(分數可以重複), redis 通過分數來爲集合中的成員進行從小到大的排序。
1. 添加 zadd
語法: zadd key score member [score member…]
作用: 將一個或多個 member 元素及其 score 值加入到有序集合 key 中,如果 member存在集合中,則更新值; score 可以是整數或浮點數
返回值: 數字, 新添加的元素個數
2. 區間查詢,升序 zrange
語法: zrange key start stop [WITHSCORES]
作用:查詢有序集合,指定區間的內的元素。 集合成員按 score 值從小到大來排序。 start, stop 都是從 0 開始。 0 是第一個元素, 1 是第二個元素,依次類推。 以 -1 表示最後一個成員, -2 表示倒數第二個成員。 WITHSCORES 選項讓 score 和 value 一同返回。
返回值:自定區間的成員集合
3. 區間查詢,降序 zrevrange
語法: zrevrange key start stop [WITHSCORES]
作用: 返回有序集 key 中,指定區間內的成員。其中成員的位置按 score 值遞減(從大到小)來排列。 其它同 zrange 命令。
返回值:自定區間的成員集合
4. 刪除 zrem
語法: zrem key member [member…]
作用: 刪除有序集合 key 中的一個或多個成員,不存在的成員被忽略
返回值:被成功刪除的成員數量,不包括被忽略的成員。
5. 獲取成員個數 zcard
語法: zcard key
作用: 獲取有序集 key 的元素成員的個數
返回值: key 存在返回集合元素的個數, key 不存在,返回 0
6. 根據分數範圍獲取元素(升序) zrangebyscore
語法: zrangebyscore key min max [WITHSCORES ] [LIMIT offset count]
作用: 獲取有序集 key 中,所有 score 值介於 min 和 max 之間(包括 min 和 max) 的成員,有序成員是按遞增(從小到大)排序。
min ,max 是包括在內,使用符號( 表示不包括。 min, max 可以使用 -inf , +inf 表示最小和最大 limit 用來限制返回結果的數量和區間。
withscores 顯示 score 和 value
返回值: 指定區間的集合數據
7. 根據分數範圍獲取元素(降序) zrevrangebyscore
語法: zrevrangebyscore key max min [WITHSCORES ] [LIMIT offset count]
作用: 返回有序集 key 中, score 值介於 max 和 min 之間(默認包括等於 max 或 min )的所有的成員。有序集成員按 score 值遞減(從大到小)的次序排列。 其他同 zrangebyscore
8. 根據分數範圍獲取元素數量 zcount
語法: zcount key min max
作用: 返回有序集 key 中, score 值在 min 和 max 之間(默認包括 score 值等於 min 或 max )的成員的數量
十、事務
事務是指一系列操作步驟,這一系列的操作步驟,要麼完全地執行,要麼完全地不執行。Redis 中的事務(transaction)是一組命令的集合,至少是兩個或兩個以上的命令, redis事務保證這些命令被執行時中間不會被任何其他操作打斷。
1. 開啓事務 multi
語法: multi
作用: 標記一個事務的開始。事務內的多條命令會按照先後順序被放進一個隊列當中。
返回值: 總是返回 ok
2. 執行 exec
語法: exec
作用: 執行所有事務塊內的命令
返回值: 事務內的所有執行語句內容,事務被打斷, 返回 nil
3. 放棄 discard
語法: discard
作用: 取消事務,放棄執行事務塊內的所有命令
返回值:總是返回 ok
4. watch
語法: watch key [key …]
作用: 在開啓事務之前,監視一個(或多個) key ,如果在事務執行(exec)之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。
返回值: 總是返回 ok
WATCH 機制: 使用 WATCH 監視一個或多個 key , 跟蹤 key 的 value 修改情況,如果有 key的 value 值在事務 EXEC 執行之前被修改了,整個事務被取消。 EXEC 返回提示信息, 表示事務已經失敗
5. unwatch
語法: unwatch
作用:取消 WATCH 命令對所有 key 的監視。如果在執行 WATCH 命令之後, EXEC 命令或 DISCARD 命令先被執行了的話,那麼就不需要再執行 UNWATCH 了
返回值:總是返回 ok
6. 事務中出錯
- 事務執行 exec 之前, 入隊命令錯誤(語法錯誤;嚴重錯誤導致服務器不能正常工作( 例如內存不足)),放棄事務。
- 事務執行 exec 命令後,命令執行錯誤,在 exec 執行後的所產生的錯誤,即使事務中有某個/某些命令在執行時產生了錯誤,事務中的其他命令仍然會繼續執行。
十一、持久化
1. RDB
Redis Database(RDB),就是在指定的時間間隔內將內存中的數據集快照寫入磁盤,數據恢復時將快照文件直接再讀到內存。
RDB 保存了在某個時間點的數據集(全部數據)。存儲在一個二進制文件中,只有一個文件。默認是 dump.rdb。 RDB 技術非常適合做備份,可以保存最近一個小時,一天,一個月的全部數據。保存數據是在單獨的進程中寫文件,不影響 Redis 的正常使用。 RDB 恢復數據時比其他 AOF 速度快。
(1)配置redis.conf
- 配置執行 RDB 生成快照文件的時間策略。
對 Redis 進行設置,讓它在“ N 秒內數據集至少有 M 個 key 改動”這一條件被滿足時,自動保存一次數據集。
配置格式: save <seconds> <changes>
save 900 1
save 300 10
save 60 10000 - dbfilename:設置 RDB 的文件名,默認文件名爲 dump.rdb
- dir:指定 RDB 文件的存儲位置,默認是 ./ 當前目錄
(2)注意點
dump.rdb文件中存放的是二進制文件。
(3)總結
優點:由於存儲的是數據快照文件,恢復數據很方便,也比較快
缺點:
- 會丟失最後一次快照以後更改的數據。 如果你的應用能容忍一定數據的丟失,那麼使用 rdb 是不錯的選擇; 如果你不能容忍一定數據的丟失,使用 rdb 就不是一個很好的選擇。
- 由於需要經常操作磁盤, RDB 會分出一個子進程。如果你的 redis 數據庫很大的話,子進程佔用比較多的時間,並且可能會影響 Redis 暫停服務一段時間(millisecond 級別),如果你的數據庫超級大並且你的服務器 CPU 比較弱,有可能是會達到一秒。
2. AOF
Append-only File(AOF), Redis 每次接收到一條改變數據的命令時,它將把該命令寫到一個 AOF 文件中(只記錄寫操作,讀操作不記錄),當 Redis 重啓時,它通過執行 AOF 文件中所有的命令來恢復數據。
(1)配置redis.conf
AOF 方式的數據持久化,僅需在 redis.conf 文件中配置即可
配置項:
- appendonly:默認是 no,改成 yes 即開啓了 aof 持久化
- appendfilename:指定 AOF 文件名,默認文件名爲 appendonly.aof
- dir:指定 RDB 和 AOF 文件存放的目錄,默認是 ./
- appendfsync:配置向 aof 文件寫命令數據的策略:
- no:不主動進行同步操作,而是完全交由操作系統來做(即每 30 秒一次),比較快但不是很安全。
- always:每次執行寫入都會執行同步,慢一些但是比較安全。
- everysec:每秒執行一次同步操作,比較平衡,介於速度和安全之間。這是默認項。
- auto-aof-rewrite-min-size:允許重寫的最小 AOF 文件大小,默認是 64M 。當 aof 文件大於 64M 時,開始整理 aof 文件,去掉無用的操作命令。縮小 aop 文件。
(2)注意點
- AOF文件中存放的命令的字符,可以打開看。
(3)總結
- append-only 文件是另一個可以提供完全數據保障的方案;
- AOF 文件會在操作過程中變得越來越大。比如,如果你做一百次加法計算,最後你只會在數據庫裏面得到最終的數值,但是在你的 AOF 裏面會存在 100 次記錄,其中 99 條記錄對最終的結果是無用的;但 Redis 支持在不影響服務的前提下在後臺重構 AOF 文件,讓文件得以整理變小
- 可以同時使用這兩種方式,redis默認優先加載 aof文件(aof數據最完整);
十二、主從複製
1. 主從配置(master/salve)
修改配置文件,啓動時,服務器讀取配置文件,並自動成爲指定服務器的從服務器,從而構成主從複製的關係
編輯 Master 的配置文件:
- daemonize:yes 後臺啓動應用,相當於 ./redis-server & 的作用。
- pidfile:自定義的文件,表示當前程序的 pid,進程 id。示例:
pidfile /var/run/redis_6379.pid
- logfile:日誌文件名
編輯 Slave 配置文件,除了配置與Master相同的那幾項外,還要額外配置一項:
- slaveof :表示當前 Redis 是誰的從。當前是 127.0.0.0 端口 6379 這個 Master 的從。示例:
slaveof 127.0.0.1 6379
2. 手動實現主從複製
(1)查看信息
在客戶端中執行:info replication
Master可以讀數據和寫數據,而Slave只能讀數據
Master的信息:
Slave的信息:
(2)容災處理
當master掛掉的時候,要提升某slave爲master,並將其它slave掛載到新的master上
- 在一臺Slave服務器上執行
slaveof no one
:將一臺 slave 服務器提升爲 Master (提升某 slave 爲 master) - 在其它服務器上執行
slaveof master的ip master的端口
將 slave 掛至新的 master 上
(3)總結
- 不配置啓動默認都是主
- 一個 master 可以有多個 slave
- slave 下線,讀請求的處理性能下降
- master 下線,寫請求無法執行
- 當 master 發生故障,需手動將其中一臺 slave 使用 slaveof no one 命令提升爲 master,其它 slave 執行 slaveof 命令指向這個新的 master,從新的 master 處同步數據
- 主從複製模式的故障轉移需要手動操作,要實現自動化處理,這就需要 Sentinel 哨兵,實現故障自動轉移。
3. 高可用 Sentinel 哨兵
Sentinel 哨兵是 redis 官方提供的高可用方案,可以用它來監控多個 Redis 服務實例的運行情況。Redis Sentinel 是一個運行在特殊模式下的 Redis 服務器。Redis Sentinel 是在多個Sentinel 進程環境下互相協作工作的。
Sentinel 系統有三個主要任務:
- 監控:Sentinel 不斷的檢查主服務和從服務器是否按照預期正常工作。
- 提醒:被監控的 Redis 出現問題時,Sentinel 會通知管理員或其他應用程序。
- 自動故障轉移:監控的主 Redis 不能正常工作,Sentinel 會開始進行故障遷移操作。將一個從服務器升級新的主服務器。讓其他從服務器掛到新的主服務器。同時向客戶端提供新的主服務器地址。
(1)配置參數
sentinel.conf中主要的配置參數:
- port:設置Sentinel的端口號,系統默認 port 是 26379
- sentinel monitor <name> <masterIP> <masterPort> <Quorum 投票數>:修改監控的 master 地址
(2)啓動哨兵
在Redis的src目錄下,有一個redis-sentinel程序文件,通過redis-sentinel來啓動哨兵,可以在一個redis中運行多個sentinel進程。
語法:./redis-sentinel sentinel配置文件
在 Master 執行 shutdown 後,稍微等一會 Sentinel 要進行投票計算,從可用的 Slave 選舉新的 Master。查看 Sentinel 日誌,三個 Sentinel 窗口的日誌是一樣的。
(3)監控
- Sentinel 會不斷檢查 Master 和 Slave 是否正常
- 如果 Sentinel 掛了,就無法監控,所以需要多個哨兵,組成 Sentinel 網絡,一個健康的Sentinel
至少有 3 個
Sentinel 應用。彼此在獨立的物理機器或虛擬機。 - 監控同一個 Master 的 Sentinel 會自動連接,組成一個分佈式的 Sentinel 網絡,互相通信並交換彼此關於被監控服務器的信息
- 當一個 Sentinel 認爲被監控的服務器已經下線時,它會向網絡中的其它 Sentinel 進行確認,判斷該服務器是否真的已經下線
- 如果下線的服務器爲主服務器,那麼 Sentinel 網絡將對下線主服務器進行自動故障轉移,通過將下線主服務器的某個從服務器提升爲新的主服務器,並讓其從服務器轉移到新的主服務器下,以此來讓系統重新回到正常狀態
- 下線的舊主服務器重新上線,Sentinel 會讓它成爲從,掛到新的主服務器下
(4)總結
主從複製,解決了讀請求的分擔,從節點下線,會使得讀請求能力有所下降,Master 下線,寫請求無法執行
Sentinel 會在 Master 下線後自動執行故障轉移操作,提升一臺 Slave 爲 Master,並讓其它Slave 成爲新 Master 的 Slave
十三、其它設置
1. 設置密碼
redis.conf中設置:
找到requirepass 所在的行,去掉註釋,requirepass 空格後就是密碼。
訪問有密碼的 Redis 兩種方式:
- 在連接到客戶端後,使用命令
auth 密碼
,命令執行成功後,可以正常使用 Redis。 - 在連接客戶端時使用
-a 密碼
。例如 ./redis-cli -h ip -p port -a password
2. 導入別的配置文件
在配置文件中使用include
參數
include :包含原來的配置文件內容。
示例:include /usr/local/redis-4.0.13/redis.conf
十四、Jedis
1. 加入依賴
Maven倉庫中查找Jedis:https://mvnrepository.com/
Jedis 對象並不是線程安全的,在多線程下使用同一個 Jedis 對象會出現併發問題。爲了避免每次使用 Jedis 對象時都需要重新構建,Jedis 提供了 JedisPool。JedisPool 是基於Commons Pool 2 實現的一個線程安全的連接池,在Maven倉庫中查找"commons pool"或者直接使用下面的依賴:
<!--Jedis依賴-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.3</version>
</dependency>
<!--Commons Pool 2依賴-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
2. 創建連接池
public class RedisUtils {
//定義連接池對象
private static JedisPool pool = null;
//創建連接池
public static JedisPool open(String host, int port) {
if (pool == null) {
//創建連接池配置對象
JedisPoolConfig config = new JedisPoolConfig();
//最大Jedis實例數(默認值爲8)
config.setMaxTotal(10);
//最大空閒連接數,設置這個可以保留足夠的連接,快速獲取連接
config.setMaxIdle(3);
//提前檢查Jedis連接,取值true表示獲取的Jedis連接一定是可用的
config.setTestOnBorrow(true);
//創建Jedis連接池,Redis沒有訪問密碼時的使用方式
pool = new JedisPool(config, host, port);
//創建Jedis連接池,Redis有訪問密碼時的使用方式
//參數:Jedis配置對象,ip,端口號,連接超時時間,訪問密碼
//pool = new JedisPool(config,host,port,6*1000,"123456");
}
return pool;
}
//關閉連接池
public static void close() {
if (pool != null) {
pool.close();
}
}
}
3. 簡單使用連接池
關鍵方法:
- 創建連接池:
JedisPool jp = RedisUtils.open("192.168.29.128", 6379);
- 從連接池中獲取jedis對象:
Jedis jedis = jp.getResource();
- 對jedis操作是通過方法實現的,方法的名稱與redis的命令一樣。
- 不使用連接池,則直接new出一個Jedis對象
public static void main(String[] args) {
try {
//創建連接池
JedisPool jp = RedisUtils.open("192.168.29.128", 6379);
//從連接池中獲取jedis對象
Jedis jedis = jp.getResource();
jedis.flushDB();
jedis.hset("hset1", "str1", "aaa");
String hget = jedis.hget("hset1", "str1");
Map<String,String> map = new HashMap<>();
map.put("id", "A0001");
map.put("name", "zs");
map.put("age", "23");
jedis.hmset("student", map);
List<String> list = jedis.hmget("student", "id", "name", "age");
System.out.println(list);
System.out.println(hget);
System.out.println(jedis);
} catch (Exception e) {
e.printStackTrace();
} finally {
RedisUtils.close();
}
}
4. 事務
事務使用的是Transaction
對象,然後使用該對象對redis數據庫進行操作,提交之後返回List,裏面存放着是否執行成功(OK/報錯)
public static void main(String[] args) {
try {
JedisPool jp = RedisUtils.open("192.168.29.128", 6379);
Jedis jedis = jp.getResource();
jedis.flushDB();
Transaction tran = jedis.multi();
tran.set("str1", "aaa1");
tran.set("str2", "bbb2");
List<Object> lis = tran.exec();
for (Object li : lis) {
System.out.println(li);//OK, OK
}
} catch (Exception e) {
e.printStackTrace();
} finally {
RedisUtils.close();
}
}