單機Mysql的年代,網站大可能是靜態網頁,動態交互性網站很少,一個網站的訪問量不大,用單個數據庫足以應付。這種單機架構的網站,數據存儲的瓶頸分爲:html
解決這種問題的技術也隨之發展,好比:mysql
Mysql的擴展性瓶頸
Mysql數據庫常常存儲一些大文本字段,致使數據庫表很是大,在作數據恢復就會很慢,不容易快速恢復數據庫。關係型數據庫很強大,可是不能應對全部的應用場景。現在是大數據年代,大數據下IO壓力大,表結構更改困難,所以須要引入Nosql。linux
NoSQL (= Not Only SQL),意爲不只僅是SQL。泛指非關係型數據庫
。隨着web2.0網站的興起,傳統數據庫在應付web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站顯得力不從心,而非關係型數據庫則因爲其自己的特色獲得迅速地發展。NoSql數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤爲大數據應用難題等。web
NoSQL種類繁多,但都有一個特色就是去掉了關係型數據庫的關係特性。正則表達式
NoSql四大分類,分爲:redis
REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value
存儲系統。
Redis是一個開源的使用ANSIC語言編寫、遵照BSD協議、支持網絡、可基於內存
亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。
它一般被稱爲數據結構服務器
,由於值(value)能夠是 字符串(String)
, 哈希(Hash)
, 列表(list)
, 集合(sets)
和 有序集合(sorted sets)
等類型。sql
官網:https://redis.io
官方下載地址:http://download.redis.io/rele...
redis命令大全:http://redisdoc.commongodb
系統環境數據庫
[root@moli_linux1 ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@moli_linux1 ~]# uname -r 3.10.0-862.6.3.el7.x86_64 [root@moli_linux1 ~]# hostname -I 192.168.30.3
安裝redisvim
[root@moli_linux1 ~]# cd /usr/local/src/ [root@moli_linux1 src]# wget http://download.redis.io/releases/redis-4.0.10.tar.gz [root@moli_linux1 src]# tar -zxvf redis-4.0.10.tar.gz [root@moli_linux1 src]# mv redis-4.0.10 /usr/local/redis [root@moli_linux1 src]# cd !$ cd /usr/local/redis [root@moli_linux1 redis]# make
至此安裝完畢。安裝完的命令在/usr/local/bin
下
[root@moli_linux1 redis]# ll /usr/local/bin/ 總用量 67304 -rwxr-xr-x. 1 root root 14413648 5月 19 2018 cmake -rwxr-xr-x. 1 root root 15543936 5月 19 2018 cpack -rwxr-xr-x. 1 root root 16574056 5月 19 2018 ctest -rwxr-xr-x 1 root root 2451240 7月 8 2018 redis-benchmark -rwxr-xr-x 1 root root 5768672 7月 8 2018 redis-check-aof -rwxr-xr-x 1 root root 5768672 7月 8 2018 redis-check-rdb -rwxr-xr-x 1 root root 2617272 7月 8 2018 redis-cli lrwxrwxrwx 1 root root 12 7月 8 2018 redis-sentinel -> redis-server -rwxr-xr-x 1 root root 5768672 7月 8 2018 redis-server
拷貝配置文件,並以新的配置文件啓動redis
[root@moli_linux1 redis]$ cp redis.conf /etc/ [root@moli_linux1 redis]$ vim /etc/redis.conf # 修改daemonize no爲daemonize yes [root@moli_linux1 redis]$ redis-server /etc/redis.conf # 啓動redis [root@moli_linux1 redis]$ ps aux | grep redis #查看進程 [root@moli_linux1 redis]$ netstat -lntp | grep redis-server
客戶端鏈接redis
[root@moli_linux1 redis]$ redis-cli -p 6379 127.0.0.1:6379>
單進程
redis是使用單進程模型來處理客戶端的請求,對讀寫等事件的響應是經過linux中epoll函數的包裝來作到的。Redis實際的處理速度徹底依靠主進程的執行效率。Epoll是Linux內核爲了處理大批量文件描述符而做了改進的epoll,是linux下多路複用IO接口select/poll的加強版本,它能顯著提升程序在大量併發鏈接中只有少許活躍的狀況下的系統CPU利用率。
數據庫
redis默認有16個數據庫,相似pyhton列表從零開始,初始默認使用0號數據庫。可在redis.conf中的database 16
中定義。
密碼
redis16個數據庫都是使用一樣的密碼,要麼都ok,要麼都鏈接失敗,設置密碼在redis.conf中的requirepass foobared
中設置,默認是註釋掉的,即沒有密碼。去掉註釋,密碼默認就是foobared,客戶端鏈接時使用auth foobared
進行認證。
端口
redis默認的端口是6379,能夠在redis.conf中的prot 6379
更改
索引
redis索引是從0開始的
命令select
命令:用於切換數據庫,好比切換到2號數據庫select 2
dbsize
命令:用於查看當前數據庫的key的數量flushdb
命令:清空當前庫flushall
命令:清空整個 Redis 服務器的數據(刪除全部數據庫的全部 key )。
列舉下經常使用的key操做命令
命令 | 說明 |
---|---|
keys pattern | 查找符合pattern(正則表達式)的key,好比keys *列出全部key |
del key | 刪除存在的key |
exists key | 判斷key是否存在 |
expire key seconds | 給指定的key設置過時時間,以秒爲單位 |
ttl key | 以秒爲單位,返回給定 key 的剩餘生存時間(TTL, time to live)。 |
type key | 返回 key 所儲存的值的類型 |
幾個注意點:
string類型是redis最基本的數據類型,一個key對應一個value,而且string類型是二進制安全的,它能夠包含任何數據,好比圖片或者序列化的對象,一個string類型的value最大能存儲512M的數據。
string命令介紹
命令 | 說明 | 示例 |
---|---|---|
set key value | 設置指定key的值 | set k1 v1 |
get key | 獲取key的值 | get k1 |
append key value | 若是key已經存在而且是一個字符串,APPEND命令將指定的value追加到該key原來值value的末尾 | append k1 v1 |
strlen key | 返回 key 所儲存的字符串值的長度 | strlen k1 |
incr key | 將 key 中儲存的數字值增一(要求value必須爲數字) | incr k2 |
decr key | 將 key 中儲存的數字值減一(要求value必須爲數字) | decr k2 |
incrby key increment | 將 key 所儲存的值加上給定的增量值 | incrby k2 3 |
decrby key increment | 將 key 所儲存的值減上給定的增量值 | decrby k2 3 |
getrange key start end | 返回 key 中字符串值的子字符 | getrange k3 0 -1 |
setrange key offset valye | 用 value 參數覆寫給定 key 所儲存的字符串值,從偏移量 offset 開始 | setrange k3 0 aaa |
setex key seconds value | 設置key的過時時間爲seconds | setex k4 10 hello |
setnx key value | 當key不存在時才設置key的值 | set k5 v5 |
mset | 同時設置一個或多個 key-value 對 | mset k6 v6 k7 v7 |
mget | 獲取全部(一個或多個)給定 key 的值 | mget k1 k2 k3 |
msetnx | 同時設置一個或多個 key-value 對,當且僅當全部給定 key 都不存在 | msetnx k8 v8 k9 v9 |
getset | 將給定 key 的值設爲 value ,並返回 key 的舊值(old value) | getset k1 v11 |
示例1,set/get/append/strlen
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> append k1 v11 # 在原先k1的值v1後添加v11 (integer) 5 127.0.0.1:6379> get k1 "v1v11" 127.0.0.1:6379> strlen k1 (integer) 5 # v1v11總共5個字符 127.0.0.1:6379>
示例2,incr/decr/incrby/decrby
127.0.0.1:6379> set k2 1 # 設置k2的值爲1 OK 127.0.0.1:6379> get k2 "1" 127.0.0.1:6379> incr k2 # incr命令使key的值加1 (integer) 2 127.0.0.1:6379> get k2 "2" # 1+1 = 2 127.0.0.1:6379> decr k2 # decr命令使key的值減1 (integer) 1 127.0.0.1:6379> get k2 "1" # 變爲1 127.0.0.1:6379> incrby k2 5 # incrby命令使key的值加上後面定義的數字 (integer) 6 127.0.0.1:6379> get k2 "6" # 1+5 = 6 127.0.0.1:6379> decrby k2 5 # decrby與incrby相反 (integer) 1 127.0.0.1:6379> get k2 "1" # 6-5 = 1
示例3,getrange/setrange
127.0.0.1:6379> set k3 abc123456 OK 127.0.0.1:6379> get k3 "abc123456" 127.0.0.1:6379> getrange k3 0 3 # 返回從0開始到3的字符串 "abc1" 127.0.0.1:6379> getrange k3 0 -1 # 返回整個字符串 "abc123456" 127.0.0.1:6379> setrange k3 0 qwe # 將從0開始的字符串覆蓋爲qwe (integer) 9 127.0.0.1:6379> get k3 "qwe123456" 127.0.0.1:6379> setrange k3 9 777 (integer) 12 127.0.0.1:6379> get k3 "qwe123456777" 127.0.0.1:6379>
示例4,setex/setnx
127.0.0.1:6379> setex k4 10 v4 # 設置k4的過時時間爲10s OK 127.0.0.1:6379> ttl k4 # 還有7s過時 (integer) 7 127.0.0.1:6379> get k4 "v4" 127.0.0.1:6379> ttl k4 (integer) -2 # 已過時 127.0.0.1:6379> get k4 (nil) 127.0.0.1:6379> 127.0.0.1:6379> get k1 "v1v11" 127.0.0.1:6379> setnx k1 hello # k1已存在,這條命令不會改變k1的值 (integer) 0 127.0.0.1:6379> get k1 "v1v11" 127.0.0.1:6379> setnx k5 hello # k5不存在,所以新建並賦值 (integer) 1 127.0.0.1:6379> get k5 "hello" 127.0.0.1:6379>
示例5,mset/mget/msetnx
127.0.0.1:6379> mset a1 dog a2 cat # 批量設置key-value OK 127.0.0.1:6379> mget a1 a2 # 批量獲取value 1) "dog" 2) "cat" 127.0.0.1:6379> msetnx a1 panda a3 lion # 其中a1以存在,這條命令執行不成功 (integer) 0 127.0.0.1:6379> mget a1 a2 a3 1) "dog" 2) "cat" 3) (nil) 127.0.0.1:6379> msetnx a3 panda a4 lion # a3和a4都不存在,所以設置key-value成功 (integer) 1 127.0.0.1:6379> mget a1 a2 a3 a4 1) "dog" 2) "cat" 3) "panda" 4) "lion" 127.0.0.1:6379>
hash類型是一個鍵值對的集合,能夠將hash看作是string key和string value的映射表,它很適合存儲對象。每個Hash能夠存儲995701749 個鍵值對。
k-v模式不變,可是value是鍵值對
經常使用命令hset key field value
:將哈希表 key 中的字段 field 的值設爲 valuehget key field
:獲取存儲在哈希表中指定字段的值。hmset key field value
:同時將多個鍵值對添加到hash表key中hmget key field1 field2
:獲取給定字段的值hgetall key
:獲取在哈希表中指定 key 的全部字段和值hdel key field1 field2
:刪除一個或多個哈希表字段
127.0.0.1:6379> hset k1 user id11 # 設置哈希表k1中user字段的值爲id11 (integer) 1 127.0.0.1:6379> hget k1 user # 獲取哈希表k1中user字段的值 "id11" 127.0.0.1:6379> hmset k1 age 22 name laowan passwd 123456 # 批量設置哈希表中的字段與值 OK 127.0.0.1:6379> hmget k1 age name passwd # 批量獲取 1) "22" 2) "laowan" 3) "123456" 127.0.0.1:6379> hgetall k1 # 批量獲取鍵值對 1) "user" 2) "id11" 3) "age" 4) "22" 5) "name" 6) "laowan" 7) "passwd" 8) "123456" 127.0.0.1:6379> hdel k1 passwd # 刪除哈希表中的字段passwd (integer) 1 127.0.0.1:6379> hgetall k1 # 已刪除 1) "user" 2) "id11" 3) "age" 4) "22" 5) "name" 6) "laowan" 127.0.0.1:6379>
hlen key
:獲取哈希表中字段的數量hexists key field
:查看哈希表中指定的字段是否存在hkeys key
:獲取哈希表中全部字段hvals key
:獲取哈希表中全部的值hincrby key field increment
:爲哈希表 key 中的指定字段的整數值加上增量 increment hincrbyfloat key field increment
:爲哈希表 key 中的指定字段的浮點數值加上增量 increment 。hsetnx key field value
:只有在字段 field 不存在時,設置哈希表字段的值。
Redis 列表是簡單的字符串列表,按照插入順序排序。你能夠添加一個元素到列表的頭部(左邊)或者尾部(右邊)。
list經常使用命令lpush key value1 value2
:將一個或多個值插入列表頭部rpush key value1 value2
:在列表中添加一個或多個值lrange key start end
:獲取列表指定範圍內的值
127.0.0.1:6379> lpush list1 1 2 3 4 5 (integer) 5 127.0.0.1:6379> lrange list1 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 5) "1" 127.0.0.1:6379> rpush list2 1 2 3 4 5 (integer) 5 127.0.0.1:6379> lrange list2 0 -1 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 127.0.0.1:6379>
lpop key
:移出並獲取列表的第一個元素rpop key
:移出並獲取列表的最後一個元素
127.0.0.1:6379> lpop list1 "5" 127.0.0.1:6379> lpop list2 "1" 127.0.0.1:6379> lrange list1 0 -1 1) "4" 2) "3" 3) "2" 4) "1" 127.0.0.1:6379> lrange list2 0 -1 1) "2" 2) "3" 3) "4" 4) "5" 127.0.0.1:6379> rpop list1 "1" 127.0.0.1:6379> rpop list2 "5" 127.0.0.1:6379>
lindex key index
:按照索引下標獲取元素llen key
:獲取列表的長度
127.0.0.1:6379> lrange list1 0 -1 1) "4" 2) "3" 3) "2" 127.0.0.1:6379> lindex list1 0 "4" 127.0.0.1:6379> lindex list1 1 "3" 127.0.0.1:6379> lindex list1 2 "2" 127.0.0.1:6379> lindex list1 3 (nil) 127.0.0.1:6379> llen list1 (integer) 3
lrem key count value
:移除列表元素
127.0.0.1:6379> rpush list3 1 1 1 2 2 2 3 3 3 4 5 6 (integer) 12 127.0.0.1:6379> lrange list3 0 -1 1) "1" 2) "1" 3) "1" 4) "2" 5) "2" 6) "2" 7) "3" 8) "3" 9) "3" 10) "4" 11) "5" 12) "6" 127.0.0.1:6379> lrem list3 2 3 # 刪除列表中2個3 (integer) 2 127.0.0.1:6379> lrange list3 0 -1 1) "1" 2) "1" 3) "1" 4) "2" 5) "2" 6) "2" 7) "3" # 原先列表有3個3,刪除了2個 8) "4" 9) "5" 10) "6" 127.0.0.1:6379>
ltrim key start end
:截取列表指定範圍的值後再賦值給列表
127.0.0.1:6379> lpush list4 1 2 3 4 5 6 (integer) 6 127.0.0.1:6379> lrange list4 0 -1 1) "6" 2) "5" 3) "4" 4) "3" 5) "2" 6) "1" 127.0.0.1:6379> ltrim list4 2 4 # 截取索引爲2到4範圍內的值(也就是4,3,2),再賦值給list4 OK 127.0.0.1:6379> lrange list4 0 -1 # 因此list4的值爲4,3,2 1) "4" 2) "3" 3) "2" 127.0.0.1:6379>
linsert key BEFORE|AFTER pivot value
:在列表的元素前或者元素後插入元素
127.0.0.1:6379> lrange list4 0 -1 1) "4" 2) "3" 3) "2" 127.0.0.1:6379> LINSERT list4 after 3 redis # 在列表的元素3後面插入元素redis (integer) 4 127.0.0.1:6379> lrange list4 0 -1 1) "4" 2) "3" 3) "redis" 4) "2" 127.0.0.1:6379> LINSERT list4 before 3 mongodb # 在列表元素3前面插入元素mongodb (integer) 5 127.0.0.1:6379> lrange list4 0 -1 1) "4" 2) "mongodb" 3) "3" 4) "redis" 5) "2" 127.0.0.1:6379>
關於list的小總結:
Redis的Set是string類型的無序集合。集合成員是惟一的,這就意味着集合中不能出現重複的數據。
集合是經過哈希表實現的,因此添加,刪除,查找的複雜度都是O(1)。
set經常使用命令sadd key m1 m2
:向集合添加一個或多個成員smembers key
:返回集合中全部的成員sismenber key member
:判斷 member 元素是不是集合 key 的成員scard key
:獲取集合裏面元素的數量srem key value
:刪除集合中的元素
127.0.0.1:6379> sadd set01 a a b b c c # 由於不能出現重複數據,所以只有三個 (integer) 3 127.0.0.1:6379> smembers set01 # 順序也不是abc,由於是無序的 1) "a" 2) "c" 3) "b" 127.0.0.1:6379> SISMEMBER set01 a # a元素存在集合set01裏 (integer) 1 127.0.0.1:6379> SISMEMBER set01 d # d元素不存在set01裏 (integer) 0 127.0.0.1:6379> scard set01 # 獲取集合set01的數量爲3個 (integer) 3 127.0.0.1:6379> SREM set01 a # 刪除集合set01中的元素a (integer) 1 127.0.0.1:6379> SMEMBERS set01 # a元素沒了 1) "c" 2) "b"
srandmember key number
:返回集合中number個隨機數
127.0.0.1:6379> sadd set02 a b c d e f g # 集合中有7個元素 (integer) 7 127.0.0.1:6379> SRANDMEMBER set02 3 # 隨機出3個元素 1) "g" 2) "d" 3) "b" 127.0.0.1:6379> SRANDMEMBER set02 3 1) "a" 2) "c" 3) "f" 127.0.0.1:6379> SRANDMEMBER set02 3 1) "c" 2) "b" 3) "f" 127.0.0.1:6379>
smove source destination member
:將 member 元素從 source 集合移動到 destination 集合
127.0.0.1:6379> sadd key3 'hello' 'world' 'foo' (integer) 3 127.0.0.1:6379> sadd key4 'bar' (integer) 1 127.0.0.1:6379> SMOVE key3 key4 'foo' (integer) 1 127.0.0.1:6379> SMEMBERS key3 1) "world" 2) "hello" 127.0.0.1:6379> SMEMBERS key4 1) "foo" 2) "bar" 127.0.0.1:6379>
sdiff key1 key2
:差集,返回給定集合之間的差集。不存在的集合 key 將視爲空集。sinter key1 key2
:交集, 不存在的集合 key 被視爲空集。當給定集合當中有一個空集時,結果也爲空集sunion key1 key2
:並集,不存在的集合 key 被視爲空集
127.0.0.1:6379> sadd key1 a b c (integer) 3 127.0.0.1:6379> sadd key2 a d c (integer) 3 127.0.0.1:6379> SDIFF key1 key2 1) "b" 127.0.0.1:6379> SDIFF key2 key1 1) "d" 127.0.0.1:6379> SINTER key1 key2 1) "a" 2) "c" 127.0.0.1:6379> SUNION key1 key2 1) "a" 2) "d" 3) "b" 4) "c"
Redis zset 和 set 同樣也是string類型元素的集合,且不容許重複的成員。
不一樣的是每一個元素都會關聯一個double類型的分數。redis正是經過分數來爲集合中的成員進行從小到大的排序。zset的成員是惟一的,但分數(score)卻能夠重複。
在set的基礎上,加了一個score值,set是k1 v1 k2 v2
,zset是k1 score1 v1 k2 score2 v2
.
經常使用命令zadd key score1 member1 [score2 member2]
:向有序集合添加一個或多個成員,或者更新已存在成員的分數zrange key start stop [WITHSCORES]
:經過索引區間返回有序集合成指定區間內的成員
127.0.0.1:6379> zadd k1 60 v1 70 v2 80 v3 90 v4 100 v5 # 建立有序集合k1和多個成員 (integer) 5 127.0.0.1:6379> zrange k1 0 -1 # 顯示成員 1) "v1" 2) "v2" 3) "v3" 4) "v4" 5) "v5" 127.0.0.1:6379> zrange k1 0 -1 withscores # 顯示分數與成員 1) "v1" 2) "60" 3) "v2" 4) "70" 5) "v3" 6) "80" 7) "v4" 8) "90" 9) "v5" 10) "100" 127.0.0.1:6379>
zrangebyscore key min max [WITHSCORES] [LIMIT]
:經過分數返回有序集合指定區間內的成員
參數withscore:顯示分數
(指不包含
limit:從索引值開始選取幾個,好比limit 2 2
指從下標爲2的值開始選取2個值
127.0.0.1:6379> ZRANGEBYSCORE k1 60 90 1) "v1" 2) "v2" 3) "v3" 4) "v4" 127.0.0.1:6379> ZRANGEBYSCORE k1 60 (90 # 分數至關於選取60<=x<90中的x值 1) "v1" 2) "v2" 3) "v3" 127.0.0.1:6379> ZRANGEBYSCORE k1 (60 (90 # 分數大於60,小於90之間的值 1) "v2" 2) "v3" 127.0.0.1:6379> ZRANGEBYSCORE k1 (60 90 1) "v2" 2) "v3" 3) "v4" 127.0.0.1:6379> ZRANGEBYSCORE k1 60 90 limit 2 2 1) "v3" 2) "v4"
ZREM key member [member ...]
:移除有序集合中的一個或多個成員
127.0.0.1:6379> zrem k1 v5 # 刪除有序集合k1中的值v5 (integer) 1 127.0.0.1:6379> zrange k1 0 -1 withscores 1) "v1" 2) "60" 3) "v2" 4) "70" 5) "v3" 6) "80" 7) "v4" 8) "90" 127.0.0.1:6379>
zcard key
:獲取有序集合的成員數zcount key min max
:計算在有序集合中指定區間分數的成員數zrank key member
:返回有序集合中指定成員的索引zscore key member
:返回有序集中,成員的分數值
127.0.0.1:6379> zrange k1 0 -1 withscores 1) "v1" 2) "60" 3) "v2" 4) "70" 5) "v3" 6) "80" 7) "v4" 8) "90" 127.0.0.1:6379> ZCARD k1 # 有序集合k1中,有四個成員 (integer) 4 127.0.0.1:6379> zcount k1 60 80 # 成員在60分到80分之間的有三個值(包含60和80) (integer) 3 127.0.0.1:6379> zcount k1 60 70 # 成員在60到70之間的有2個 (integer) 2 127.0.0.1:6379> zrank k1 v4 # 成員v4在有序集合中索引值爲3 (integer) 3 127.0.0.1:6379> zscore k1 v4 # 成員v4在有序集合中的分數是90 "90" 127.0.0.1:6379>
命令不少,多多練習,沒必要死記硬背。
redis.conf的路徑一般在安裝目錄下。不過linux中一般不會直接修改自己的配置文件,而是拷貝一份進行配置。
是否後臺運行,默認爲no
daemonize yes
設置tcp的backlog,非高併發環境默認便可。
tcp-backlog 511
backlog是一個鏈接隊列,隊列總和=未完成三次握手隊列+已完成三次握手隊列。高併發環境下須要一個高的backlog值來避免客戶端鏈接過慢的問題。注意Linux內核會將這個值減少到/proc/sys/net/core/somaxconn的值,因此須要確認增大somaxconn和tcp_max_syn_backlog這兩個值。
默認端口
port 6379
指定IP監聽
bind 127.0.0.1 ip2 ip3 ip4
定義redis進程PID文件
pidfile /var/run/redis_6379.pid
設置redis日誌級別
loglevel notice
Redis默認有四種日誌級別
debug (a lot of information, useful for development/testing)# 開發測試階段使用
verbose (many rarely useful info, but not a mess like the debug level)#
notice (moderately verbose, what you want in production probably)
warning (only very important / critical messages are logged) #生產中使用
日誌文件位置
logfile /var/log/redis.log
redis數據庫數量,默認16個,redis-cli中使用select切換數據庫
databases 16
設置密碼,默認是註釋的即沒密碼,設置密碼打開註釋,修改foobared便可
redis-cli中使用auth password
進行認證
requirepass foobared
禁止protected-mode
protected-mode yes/no (保護模式,是否只容許本地訪問)
AOF日誌開關是否打開
appendonly no/yes
指定AOF日誌的文件名
appendfilename appendonly.aof
指定更新日誌的條件,有3個可選值
no:表示等操做系統進行數據緩存同步到磁盤(快) always:表示每次更新操做後調用fsync()將數據寫到磁盤(慢,安全) everysec:表示每秒同步一次(默認值)
指定Redis最大內存限制,Redis在啓動時會把數據加載到內存中,達到最大內存後,Redis會嘗試清除已到期或者即將到期的key。當此方法處理後,仍然達到最大內存設置,將沒法進行寫入操做,但能夠進行讀取操做。Redis新的vm機制,會將key存放內存,value存放swap區。
maxmemory <bytes>
當客戶端閒置多長時間後關閉鏈接,若是指定爲0,表示關閉改功能
timeout 300
RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,也就是SNAPSHOT快照,它恢復時是將快照文件直接讀取到內存裏。
優勢
Redis會單首創建(fork)一個子進程來進行持久化,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,再用這個臨時文件替換上一次持久化好的文件。整個過程當中,主進程不進行任何IO操做,確保了極高的性能。若是須要進行大規模數據的恢復,且對於數據恢復的完整性不那麼敏感,那麼RDB比AOF會高效許多。
缺點
最後一次持久化的數據可能丟失。
每次保存 RDB 的時候,Redis 都要 fork() 出一個子進程,並由子進程來進行實際的持久化工做。 在數據集比較龐大時, fork() 可能會很是耗時,形成服務器在某某毫秒內中止處理客戶端;若是數據集很是巨大,而且 CPU 時間很是緊張的話,那麼這種中止時間甚至可能會長達整整一秒。 雖然 AOF 重寫也須要進行 fork() ,但不管 AOF 重寫的執行間隔有多長,數據的耐久性都不會有任何損失。
RDB持久化配置
修改redis.conf配置文件
save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /data/redis/
對應的含義是:
就將內存中的數據寫入到dump.rdb文件中。
若是不設置RDB持久化只須要更改成save ""
便可。
注意:在redis-cli中執行flushall會馬上刷新dump.rdb文件。
如何恢復以前的數據
假如已經保存了一個dump.rdb文件,可是redis-cli中執行了一次flushall命令,此時內存中已經沒有任何數據了,可是又想恢復到原來的數據,應該怎麼作?
作個小測試:
先修改redis.conf配置文件
save 30 5 # 即30秒內有5次更改就將內存的數據寫入dump.rdb
而後redis-cli裏在30s內寫入5個數據。
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> set k3 v3 OK 127.0.0.1:6379> set k4 v4 OK 127.0.0.1:6379> set k5 v5 OK
退出後能夠看到新生成的dump.rdb文件
[root@moli_linux1 redis]# ll 總用量 4 -rw-r--r-- 1 root root 133 3月 27 14:52 dump.rdb # 注意此處的時間 [root@moli_linux1 redis]# cp dump.rdb dump.rdb.bak # 將這個文件備份
生產中應該講備份文件放置在其餘機器,測試所用就放在本地上了。
再次進入redis-cli執行flushall
命令
127.0.0.1:6379> flushall OK 127.0.0.1:6379> exit [root@moli_linux1 redis]# ll dump.rdb -rw-r--r-- 1 root root 93 3月 27 14:56 dump.rdb # 馬上新生成的dump.rdb文件
此時重啓redis服務,以前的持久化數據不會保存,由於重啓加載的文件仍是flushall後的dump.rdb文件。
要想恢復以前的數據只要把保存的dump.rdb文件從新加載進去便可。
[root@moli_linux1 redis]# rm -f dump.rdb # 刪除flushall保存的dump.rdb [root@moli_linux1 redis]# mv dump.rdb.bak dump.rdb # 把備份的文件更改成redis啓動時讀取的文件 [root@moli_linux1 redis]# redis-server /etc/redis.conf 9377:C 27 Mar 15:07:11.066 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 9377:C 27 Mar 15:07:11.066 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=9377, just started 9377:C 27 Mar 15:07:11.066 # Configuration loaded [root@moli_linux1 redis]# redis-cli 127.0.0.1:6379> keys * # 數據恢復 1) "k5" 2) "k3" 3) "k2" 4) "k1" 5) "k4"
備份
AOF以日誌的形式來記錄每一個寫操做,將Redis執行過的全部寫命令記錄下來(讀操做不記錄),只許追加文件但不能夠改寫文件,redis啓動時會讀取該文件從新構建數據,會將文件中的命令從新執行一遍以完成數據恢復。
AOF保存的是appendonly.aof文件。
AOF配置
appendonly no appendfilename "appendonly.aof" appendfsync always appendfsync everysec appendfsync no no-appendfsync-on-rewrite yes/no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
對於配置分別表示
關於AOF的重寫rewrite
AOF採用文件追加的方式,文件會愈來愈大,爲避免出現這種狀況,新增了重寫機制,當AOF文件的大小超過所定的閾值,redis就會啓動AOF文件內容壓縮,只保留能夠恢復數據的最小指令集,可使用命令bgrewriteaof
AOF的重寫原理(減肥計劃):
AOF文件持續增大而過大,會fork出一條新進程來將文件重寫(先寫臨時文件最後再rename),遍歷新進程中的內存數據,每條記錄有一條set語句。重寫aof文件的操做,並無讀取舊的aof文件。而是將整個內存中的數據庫內容用命令的方式重寫一個新的aof文件。
AOF的觸發機制:
reids會記錄上次重寫aof文件的大小,默認配置是當aof文件大小是上次rewrite後大小的一倍且文件大小大於64M時觸發。
AOF優勢
使用AOF 會讓你的Redis更加耐久: 你可使用不一樣的fsync策略:無fsync,每秒fsync,每次寫的時候fsync.使用默認的每秒fsync策略,Redis的性能依然很好(fsync是由後臺線程進行處理的,主線程會盡力處理客戶端請求),一旦出現故障,你最多丟失1秒的數據.
Redis 能夠在 AOF 文件體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。 整個重寫操做是絕對安全的,由於 Redis 在建立新 AOF 文件的過程當中,會繼續將命令追加到現有的 AOF 文件裏面,即便重寫過程當中發生停機,現有的 AOF 文件也不會丟失。
一旦新 AOF 文件建立完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操做。
AOF 文件有序地保存了對數據庫執行的全部寫入操做, 這些寫入操做以 Redis 協議的格式保存, 所以 AOF 文件的內容很是容易被人讀懂, 對文件進行分析(parse)也很輕鬆。 導出(export) AOF 文件也很是簡單: 舉個例子, 若是你不當心執行了 FLUSHALL 命令, 但只要 AOF 文件未被重寫, 那麼只要中止服務器, 移除 AOF 文件末尾的 FLUSHALL 命令, 並重啓 Redis , 就能夠將數據集恢復到 FLUSHALL 執行以前的狀態。
AOF缺點
對於相同數據集的數據而言,AOF文件要遠大於RDB文件,恢復速度慢與RDB
AOF運行效率要慢於RDB,每秒同步策略較好,不一樣步效率和RDB相同。
若是AOF文件損壞了怎麼辦?
生產環境下,若是由於斷電而致使AOF寫入的數據不完整, 致使AOF文件出錯,那麼當redis重啓的時候就會拒絕載入這個AOF文件,保證數據的一致性。若是發生這種狀況可使用redis自帶的redis-check-aof
進行修復。
redis-check-aof -fix appendonly.aof
命令進行修復dump.rdb和appendonly.aof文件可否共存?
先看下配置文件的註釋
AOF and RDB persistence can be enabled at the same time without problems.
If the AOF is enabled on startup Redis will load the AOF, that is the file
with the better durability guarantees.
翻譯過來大概是:RDB和AOF持久化策略能夠同時開啓,若是AOF和RDB都開啓,那麼redis服務器每次重啓時都會優先使用AOF文件恢復數據集。
如何選擇RDB仍是AOF
redis事務,主從,消息訂閱,事務,慢日誌後續再作筆記。禿頭才能變強,加油!