一、安裝
1. 官網(wǎng)下載源碼
2. 安裝依賴包
yum install gcc tcl
3. 下載源碼包
wget http://download.redis.io/releases/redis-4.0.10.tar.gz
3. 解壓安裝
tar -xf redis-4.0.10.tar.gz
cd redis-4.0.10
make && make install
4. 配置 redis
mkdir /etc/redis
cd redis-4.0.10/
cp redis.conf /etc/redis/6379.conf
守護(hù)進(jìn)程的方式啟動(dòng)服務(wù)時(shí)前弯,即使執(zhí)行啟動(dòng)服務(wù)命令的終端關(guān)閉适滓,服務(wù)仍然可以在后臺(tái)運(yùn)行仆邓。
配置 centos7 systemd 管理 redis 服務(wù)
- 在
/lib/systemd/system
目錄下創(chuàng)建一個(gè)腳本文件redis.service暑始,里面的內(nèi)容如下:
[Unit]
Description=Redis
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/redis-server /etc/redis/6379.conf --daemonize no
ExecStop=/usr/local/bin/redis-cli -p 6379 shutdown
[Install]
WantedBy=multi-user.target
[Unit] 表示這是基礎(chǔ)信息配置塊
Description 是描述
After 開啟自啟動(dòng)時(shí)候的順序, 指定的服務(wù)必須先于次此服務(wù)啟動(dòng),一般是網(wǎng)絡(luò)服務(wù)啟動(dòng)后啟動(dòng)
[Service] 表示這里是服務(wù)信息配置塊
Type 指定啟動(dòng)服務(wù)的類型, simple 是默認(rèn)的方式
EnvironmentFile 指定服務(wù)啟動(dòng)時(shí)用到的配置文件
ExecStart 是啟動(dòng)服務(wù)的命令
ExecStop 是停止服務(wù)的指令
[Install] 表示這是是安裝信息配置塊
WantedBy 是以哪種方式啟動(dòng):multi-user.target表明當(dāng)系統(tǒng)以多用戶方式(默認(rèn)的運(yùn)行級(jí)別)啟動(dòng)時(shí)搅窿,這個(gè)服務(wù)需要被自動(dòng)運(yùn)行嘁酿。
授權(quán)在主機(jī)啟動(dòng)的時(shí)候同時(shí)啟動(dòng)服務(wù)
systemctl enable redis.service
關(guān)于 server
文件的詳細(xì)參數(shù)介紹參考這里
- 使用 systemctl 操作
刷新配置疾棵,讓 systemd
識(shí)別剛剛添加的 redis
服務(wù)
systemctl daemon-reload
啟動(dòng)服務(wù)
systemctl start redis
關(guān)于配置文件中的配置
設(shè)置監(jiān)聽地址
shell> vi /etc/redis/63779.conf
# bind 127.0.0.1 192.168.1.10
bind
參數(shù)若都注釋掉,則會(huì)監(jiān)聽服務(wù)器上的所有 ip
可以指定一個(gè)或者多個(gè)痹仙,打開注釋是尔。
注意此配置項(xiàng)可能在71
行左右。默認(rèn)是bind 127.0.0.1
檢查并測(cè)試
檢查默認(rèn)端口 6379
是否監(jiān)聽
``
shell> redis-cli
127.0.0.1:6379> info
# Server
redis_version:4.0.10
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:cfb22f7d67db356d
... 略 ...
手動(dòng)使用命令指定配置文件啟動(dòng)服務(wù)
/usr/local/bin/redis-server /etc/redis/6379.conf
這種方式執(zhí)行开仰,默認(rèn)
Redis
服務(wù)侯會(huì)在前臺(tái)運(yùn)行拟枚。
設(shè)置使用守護(hù)進(jìn)程都方式運(yùn)行服務(wù)
需要編輯配置文件 /etc/redis/6379.conf
daemonize yes # 守護(hù)進(jìn)程的方式啟動(dòng)服務(wù)
客戶端指定端口訪問
redis-cli -p 6379
手動(dòng)停止服務(wù)
redis-cli -p 6379 shutdown
假如重啟后出現(xiàn)如下錯(cuò)誤信息,就按照提示操作
1044:M 27 Feb 14:47:21.993 # Server initialized
1044:M 27 Feb 14:47:21.993 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1044:M 27 Feb 14:47:21.993 # Short read or OOM loading DB. Unrecoverable error, aborting now.
1044:M 27 Feb 14:47:21.993 # Internal error in RDB reading function at rdb.c:1666 -> Unexpected EOF reading RDB file
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
sysctl -p
問題二
error, aborting now.
1344:M 27 Feb 14:59:33.466 # Internal error in RDB reading function at rdb.c:1666 -> Unexpected EOF reading RDB file
移動(dòng) dump.db
文件或者更名众弓,可以刪除恩溅。
rm dump.rdb
二、數(shù)據(jù)類型
1. 數(shù)據(jù)類型的基本介紹
2. 數(shù)據(jù)類型的基本操作
a.String
set
127.0.0.1:6379> help set
SET key value [EX seconds] [PX milliseconds] [NX|XX]
在 Redis 中設(shè)置值谓娃,默認(rèn)脚乡,不存在則創(chuàng)建,存在則修改
參數(shù):
ex滨达,過期時(shí)間(秒)
px奶稠,過期時(shí)間(毫秒)
nx,假如設(shè)置為True捡遍,則只有 name 不存在時(shí)锌订,當(dāng)前 set 操作才執(zhí)行
xx,假如設(shè)置為True画株,則只有 name 存在時(shí)辆飘,當(dāng)前 set 操作才執(zhí)行
Example
127.0.0.1:6379> set name shark EX 10
OK
127.0.0.1:6379> get name
"shark"
setnx
127.0.0.1:6379> help setnx
SETNX key value
設(shè)置值,只有name
不存在時(shí)谓传,執(zhí)行設(shè)置操作(添加)
Example
127.0.0.1:6379> setnx age 10
(integer) 1
127.0.0.1:6379> get age
"10"
127.0.0.1:6379> setnx age 20
(integer) 0
127.0.0.1:6379> get age
"10"
127.0.0.1:6379>
setex
127.0.0.1:6379> help setex
SETEX key seconds value
設(shè)置 key 和 value蜈项,并且指的過期時(shí)間(單位: 秒)
Example
127.0.0.1:6379> setex name 5 shark
OK
get
獲取一個(gè) key 的 value
127.0.0.1:6379> get name
"shark"
ttl
查看一個(gè) key 的過期時(shí)間
127.0.0.1:6379> ttl age
(integer) -1
- -1 永不過期
- -2 已經(jīng)過期
expire
設(shè)置一個(gè) key 的過期時(shí)間(單位: 秒)
127.0.0.1:6379> EXPIRE age 10
(integer) 1
127.0.0.1:6379> ttl age
(integer) 7
persist key
移除 key
的過期時(shí)間
mset
一次添加多個(gè)值
127.0.0.1:6379> mset name shark age 10
OK
mget
一次獲取多個(gè) key 的值
127.0.0.1:6379> MGET name age
1) "shark"
2) "10
inrc
對(duì)一個(gè) key 的值自增 1
127.0.0.1:6379> incr age
(integer) 11
decr
對(duì)一個(gè) key 的值自減 1
127.0.0.1:6379> DECR age
(integer) 10
append
向一個(gè) key 的值后面追加內(nèi)容
127.0.0.1:6379> get n
"10"
127.0.0.1:6379> APPEND n 10
(integer) 4
127.0.0.1:6379> get n
"1010"
getrange
127.0.0.1:6379> GETRANGE n 0 -1
"1010"
del
刪除 一個(gè)或者多個(gè) key
127.0.0.1:6379> del name age
(integer) 2
EXISTS
判斷一個(gè) key 是否存在, 返回 1 表示存在, 0 表示不存在
TYPE
返回key存儲(chǔ)的類型续挟,如果不存在則返回none
type key
keys
通過通配符來獲取匹配到的 key
一般不在生產(chǎn)環(huán)境中使用此命令
-
*
匹配所有 -
?
匹配任意一個(gè)
127.0.0.1:6379> keys *
1) "num"
2) "age"
3) "n"
127.0.0.1:6379> keys n*
1) "num"
2) "n"
127.0.0.1:6379> keys a[f-g]
(empty list or set)
127.0.0.1:6379> keys a[e-g]?
1) "age"
scan
dbsize
返回?cái)?shù)據(jù)庫(kù)種 key
的總數(shù)
dbsize
EXPIRE
設(shè)置key的過期時(shí)間紧卒,如果key不存在則返回0,否則返回1.如果key已經(jīng)存在過期時(shí)間則再設(shè)置會(huì)覆蓋之前的過期時(shí)間
b. List
操作
lpush
向列表左端添加元素庸推,values是按左到右依次插入的常侦,返回值為列表中元素個(gè)數(shù)浇冰,列表元素可以重復(fù)
最后加入到元素贬媒,在列表的第一位
127.0.0.1:6379> LPUSH list a b c
(integer) 3
127.0.0.1:6379> LPUSH list a b c
(integer) 6
rpush
向列表右端依次的添加元素,最后加入的元素在列表的最后位置
127.0.0.1:6379> RPUSH list d e f
(integer) 9
LINDEX
通過元素在列表中的位置獲取到這個(gè)元素肘习,位置稱為索引號(hào)/下標(biāo)际乘,
位置支持正整數(shù)和負(fù)整數(shù)
列表中元素的位置中,第一位是 0漂佩,最后一位是列表總長(zhǎng)度減 1 或者是 -1
127.0.0.1:6379> LINDEX list 0
"c"
LRANGE
獲取列表表一個(gè)區(qū)間的值
127.0.0.1:6379> LRANGE list 0 2
1) "c"
2) "b"
3) "a"
LPUSHX
向列表左端添加元素脖含,只有key存在時(shí)才可以添加
127.0.0.1:6379> EXISTS list1
(integer) 0
127.0.0.1:6379> LPUSHX list1 a
(integer) 0
127.0.0.1:6379> LPUSHX list g
(integer) 10
RPUSHX
向列表右端添加元素罪塔,其他與LPUSHX相同
LPOP
將左端列表元素彈出,會(huì)將其從列表中刪除养葵,如果key不存在則返回(nil)
127.0.0.1:6379> LPOP list
"g"
127.0.0.1:6379> LPOP list
"c"
RPOP
將右端列表元素彈出征堪,其他同LPOP
LLEN
返回列表的長(zhǎng)度,如果列表不存在則返回0
127.0.0.1:6379> LLEN list
(integer) 8
127.0.0.1:6379> LLEN list1
(integer) 0
LREM
lrem key count value
刪除列表中指定的值关拒,返回值為刪除的元素的個(gè)數(shù)佃蚜,count值有以下幾種:
- count > 0: 從列表的頭開始,向尾部搜索着绊,移除與value相等的元素谐算,移除count個(gè)
- count < 0: 從列表尾部開始,向頭部搜索归露,移除與value相等的元素洲脂,移除-count個(gè)
- count == 0: 移除列表中所有與value相等的
c. Hash
HSET key field value
將哈希表key中的域 (field) 設(shè)置成指定的value,如果key不存在則新建一個(gè)hash表剧包,如果域不存在則新建域恐锦,如果域已存在則更新域,如果field不存在返回1表示新建疆液,存在則返回0表示更新
127.0.0.1:6379> HSET userinfo username 'shark'
(integer) 1
127.0.0.1:6379> HSET userinfo userpsw '123456'
(integer) 1
127.0.0.1:6379> HSET userinfo userpsw '654321'
(integer) 0
HGET key field
獲取哈希表key中的域field的值踩蔚,如果key或者field不存在則返回(nil)
127.0.0.1:6379> HGET userinfo2 username
(nil)
127.0.0.1:6379> HGET userinfo username
"stronger"
127.0.0.1:6379> HGET userinfo email
(nil)
HSETNX key field value
將哈希表中的域field設(shè)置成指定的值,只有field不存在時(shí)才可以成功枚粘,如果field存在操作無效馅闽,返回0
127.0.0.1:6379> HGET userinfo username
"stronger"
127.0.0.1:6379> HSETNX userinfo username 'fish'
(integer) 0
127.0.0.1:6379> HGET userinfo username
"stronger"
HMSET key field vale [field value]
同時(shí)將多個(gè)field-value設(shè)定到hash表中,如果field已存在值則會(huì)被覆蓋掉
127.0.0.1:6379> HMSET userinfo email 'yangdm@gmail.com' sex 'male'
OK
HMGET key field [field]
同時(shí)獲得key存儲(chǔ)的hansh表中多個(gè)field的值馍迄,如果不存在則返回(nil)
127.0.0.1:6379> HMGET userinfo email sex age
1) "yangdm@gmail.com"
2) "male"
3) (nil)
HGETALL key
返回key存儲(chǔ)的所有field及value
127.0.0.1:6379> HGETALL userinfo
1) "username"
2) "stronger"
3) "userpsw"
4) "654321"
5) "email"
6) "yangdm@gmail.com"
7) "sex"
8) "male"
127.0.0.1:6379> HGETALL userinfo2
(empty list or set)
HKEYS key
返回hash的所有域
127.0.0.1:6379> HKEYS userinfo
1) "username"
2) "userpsw"
3) "email"
4) "sex"
HVALS key
返回hash的所有域的值
127.0.0.1:6379> HVALS userinfo
1) "stronger"
2) "654321"
3) "yangdm@gmail.com"
4) "male"
HEXISTS key field
檢測(cè)key中存儲(chǔ)的hash中field是否存在福也,存在返回1,否則返回0
127.0.0.1:6379> HEXISTS userinfo username
(integer) 1
127.0.0.1:6379> HEXISTS userinfo age
(integer) 0
HLEN key
返回key中存儲(chǔ)的hash表中field的數(shù)量
127.0.0.1:6379> HLEN userinfo
(integer) 4
HINCRBY key field increment
給key中存儲(chǔ)的hash表field增加increment攀圈,如果此field不存在暴凑,則創(chuàng)建值為0的field,然后增加increment赘来。操作的字段必須是整數(shù)现喳,參照字符串處理
127.0.0.1:6379> HINCRBY userinfo age 10
(integer) 10
HINCRBYFLOAT key field increment
給key中存儲(chǔ)的hash表field增加increment,可以為浮點(diǎn)數(shù)犬辰,參照字符串處理
127.0.0.1:6379> HINCRBYFLOAT userinfo salary 150.56
"150.56"
HDEL key field [field]
刪除key中存儲(chǔ)的hash表的field嗦篱,可以刪除一個(gè)或多個(gè),成功返回被移除域的數(shù)量
127.0.0.1:6379> HKEYS userinfo
1) "username"
2) "userpsw"
3) "email"
4) "sex"
5) "age"
6) "salary"
127.0.0.1:6379> HDEL userinfo salary age
(integer) 2
127.0.0.1:6379> HKEYS userinfo
1) "username"
2) "userpsw"
3) "email"
4) "sex"
Set
Redis 的 Set 是 String 類型的無序集合。集合成員是唯一的幌缝,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)灸促。
Redis 中集合是通過哈希表實(shí)現(xiàn)的。
// 向集合中添加一個(gè)或者多個(gè)元素
SADD key member [member ...]
// 獲取集合中元素的個(gè)數(shù)
SCARD key
// 返回所有集合的差集,就是存在于第一個(gè)集合中浴栽,且不存在于其他集合中的成員
SDIFF key [key ...]
// 交集,就是所有集合共有的元素
SINTER key [key ...]
// 并集典鸡, 就是所有集合的元素合并在一起被廓,并去重
SUNION key [key ...]
// 返回一個(gè)集合中的所有成員
SMEMBERS key
Example
127.0.0.1:6379> sadd s1 a b
(integer) 2
127.0.0.1:6379> sadd s2 a b c d
(integer) 4
127.0.0.1:6379> sadd s3 c d e f
(integer) 4
127.0.0.1:6379> sdiff s2 s1
1) "d"
2) "c"
127.0.0.1:6379> SINTER s1 s2
1) "b"
2) "a"
127.0.0.1:6379> SUNION s1 s2 s3
1) "b"
2) "c"
3) "d"
4) "f"
5) "a"
6) "e"
127.0.0.1:6379> SMEMBERS s1
1) "b"
2) "a"
Sort Set 操作
有序集合,在集合的基礎(chǔ)上萝玷,為每元素排序伊者;元素的排序需要根據(jù)另外一個(gè)值來進(jìn)行比較,所以间护,對(duì)于有序集合亦渗,每一個(gè)元素有兩個(gè)值,即:值和分?jǐn)?shù)汁尺,分?jǐn)?shù)專門用來做排序法精。
// 向有序集合添加一個(gè)或多個(gè)成員,或者更新已存在成員的分?jǐn)?shù)
ZADD key score1 member1 [score2 member2]
// 獲取有序集合的元素個(gè)數(shù)
ZCARD key
出現(xiàn)下面的錯(cuò)誤痴突,是操作的命令和這個(gè)命令所能操作的數(shù)據(jù)類型不符合搂蜓。
(error) WRONGTYPE Operation against a key holding the wrong kind of value
三、Redis 的認(rèn)證連接
// 在配置文件中找到以下配置項(xiàng)辽装,大約在第 `500` 行
shell> vi /etc/redis/6379.conf
requirepass mypassword
mypassword
就是密碼了帮碰,更改好后重啟服務(wù)
使用設(shè)置好的密碼認(rèn)證
// 使用 auth 進(jìn)行密碼認(rèn)證
127.0.0.1:6379> info
NOAUTH Authentication required.
127.0.0.1:6379> auth mypassword
OK
127.0.0.1:6379> info
# Server
redis_version:4.0.10
...略...
或者在 shell 命令行里使用 -a
選項(xiàng)指定密碼,會(huì)出現(xiàn)警告信息
[root@localhost ~]# redis-cli -a foobared info
Warning: Using a password with '-a' option on the command line interface may not be safe.
# Server
redis_version:4.0.10
...略...
四拾积、php-redis
開始在 PHP 中使用 Redis 前殉挽, 我們需要確保已經(jīng)安裝了 redis 服務(wù)及 PHP redis 驅(qū)動(dòng),且你的機(jī)器上能正常使用 PHP拓巧。
安裝 phpredis 驅(qū)動(dòng)
點(diǎn)我進(jìn)入下載頁(yè)面斯碌,,注意選擇版本
1. 下載解壓后,進(jìn)入解壓后的目錄
[root@s2 ~]# wget https://github.com/phpredis/phpredis/archive/4.2.0.tar.gz
shell>
shell> cd php7-redis
2. 安裝 php
安裝 php , 只需要使用 YUM 安裝 php-devel
即可肛度。
yum install php-devel
3. 執(zhí)行如下命令傻唾,生成配置工具
在解壓后的 php 目錄中執(zhí)行如下命令
shell> phpize
4. 使用生成的配置工具命令 configre
進(jìn)行配置并編譯安裝
[root@s2 phpredis-4.2.0]# find / -name php-config
/usr/bin/php-config
[root@s2 phpredis-4.2.0]# ./configure --with-php-config=/usr/bin/php-config
... 略...
checking whether to build shared libraries... yes
checking whether to build static libraries... no
configure: creating ./config.status
config.status: creating config.h
config.status: executing libtool commands
[root@s2 phpredis-4.2.0]# make && make install
...略...
Build complete.
Don't forget to run 'make test'.
Installing shared extensions: /usr/lib64/php/modules/
5. 測(cè)試安裝是否成功
[root@s2 phpredis-4.2.0]# php -v
PHP 5.4.16 (cli) (built: Oct 30 2018 19:30:51)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
6. 在php.ini中添加 extension=redis.so
[root@s2 phpredis-4.2.0]# find / -name php.ini
/etc/php.ini
[root@s2 phpredis-4.2.0]# vi /etc/php.ini
[root@s2 phpredis-4.2.0]# tail /etc/php.ini
;mcrypt.modes_dir=
[dba]
;dba.default_handler=
; Local Variables:
; tab-width: 4
; End:
extension=redis.so
[root@s2 phpredis-4.2.0]# php -m | grep redis
redis
7. php -m | grep redis或者phpinfo查看安裝是否成功
[root@s2 phpredis-4.2.0]# php -m | grep redis
redis
五、持久化存儲(chǔ)
1. 持久化存儲(chǔ)的方式介紹
Redis 分別提供了 RDB 和 AOF 兩種持久化機(jī)制:
RDB 將數(shù)據(jù)庫(kù)的快照(snapshot)以二進(jìn)制的方式保存到磁盤中承耿。
AOF 則以協(xié)議文本的方式冠骄,將所有對(duì)數(shù)據(jù)庫(kù)進(jìn)行過寫入的命令(及其參數(shù))記錄到 AOF 文件,以此達(dá)到記錄數(shù)據(jù)庫(kù)狀態(tài)的目的加袋。
2. RDB
a. 什么是RDB
和 MySQL 中的 mysqldump
差不多一個(gè)道理凛辣。
b. 什么情況下會(huì)觸發(fā) RDB
第一種情況,主動(dòng)執(zhí)行 save
命令(同步锁荔,阻塞 蟀给,就是save
命令執(zhí)行完畢后才能執(zhí)行后續(xù)的其他命令操作)
阻塞
保存 RDB 文件的策略
每次創(chuàng)建新的文件蝙砌,并且替換原來舊文件(假如存在舊的文件)
第二種情況阳堕,主動(dòng)執(zhí)行 bgsave
命令 (異步跋理,非阻塞 )
- 文件策略和
save
相同
第三種情況,自動(dòng)觸發(fā)
自動(dòng)觸發(fā)恬总,就是通過對(duì) Redis 的配置文件重相關(guān)選項(xiàng)的修改前普,當(dāng)達(dá)到某個(gè)配置好的條件后,自動(dòng)生成 RDB 文件
壹堰,其內(nèi)部使用的是 bgsave
命令拭卿。
配置文件中相關(guān)選項(xiàng)的默認(rèn)值如下表:
配置 | seconds | changes | 含義 |
---|---|---|---|
save | 900 | 1 | 每隔 900 秒檢查一次,假如至少有 1 條數(shù)據(jù)改變贱纠,就生成新的 RDB 文件 |
save | 300 | 10 | 每隔 300 秒檢查一次峻厚,假如至少有 10 條數(shù)據(jù)改變,就生成新的 RDB 文件 |
save | 60 | 10000 | 每隔 60 秒檢查一次谆焊,假如至少有 10000 條數(shù)據(jù)改變惠桃,就生成新的 RDB 文件 |
每次檢查都會(huì)建立一個(gè)新的檢查點(diǎn),以便用于下次檢查作為參考信息辖试。
關(guān)于 RDB 文件的配置信息
默認(rèn)文件名
dbfilename dump.rdb
默認(rèn)文件保存位置
dir ./
假如
bgsave
執(zhí)行中發(fā)生錯(cuò)誤辜王,是否停止寫入,默認(rèn)是yes
罐孝, 表示假如出錯(cuò)呐馆,就停止寫入。
stop-writes-on-bgsave-error yes
是否使用壓縮|
rdbcompression yes
是否進(jìn)行數(shù)據(jù)的校驗(yàn)
rdbchecksum yes
建議的最佳配置
關(guān)閉自動(dòng)生成 RDB 文件
在配置文件中注釋掉如下內(nèi)容
#save 900 1
#save 300 10
#save 60 10000
使用不同端口號(hào)進(jìn)行區(qū)分莲兢,因?yàn)樾诶矗锌赡軙?huì)在同一臺(tái)主機(jī)上開啟多個(gè) Redis 實(shí)例。
防止多個(gè)實(shí)例產(chǎn)生的數(shù)據(jù)信息寫到一個(gè)文件中改艇。
dbfilename dump-${port}.rdb
指定一個(gè)大硬盤的路徑
dir /redis_data
假如出現(xiàn)錯(cuò)誤俗慈,停止繼續(xù)寫入
stop-writes-on-bgsave-error yes
采用壓縮
rdbcompression yes
進(jìn)行校驗(yàn)
rdbchecksum yes
實(shí)驗(yàn)
修改配置文件中的相關(guān)選項(xiàng),使其成為如下內(nèi)容中顯示的值:
dbfilename dump-6379.rdb
dir /redis_data # 此目錄需要自己創(chuàng)建
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
假如你的 Redis 服務(wù)器允許客戶端可以從非本機(jī)訪問遣耍,應(yīng)該在配置文件中闺阱,把 protected-mode
的值設(shè)置問 no
。
這樣的話舵变,客戶端就可以從其他主機(jī)訪問 Redis 服務(wù)器了酣溃,并且不需要密碼。
重啟服務(wù)后纪隙,在 Rdis 命令行客戶端中輸入 save
命令赊豌。
[root@s1 ~]# redis-cli
127.0.0.1:6379> save
OK
127.0.0.1:6379>
該命令將在配置文件重配置的指定目錄中創(chuàng)建 dump-6379.rdb
文件。
恢復(fù)數(shù)據(jù)時(shí)绵咱,只需要保證此文件完好碘饼,并且在配置文件中指定的目錄下即可。這樣 Rdis 啟動(dòng)時(shí)就會(huì)把此文件中的數(shù)據(jù)恢復(fù)到當(dāng)前的服務(wù)器中。
bgsave
命令和 save
基本一樣艾恼,就是 bgsave
命令不會(huì)產(chǎn)生阻塞
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379>
查看當(dāng)前服務(wù)器的數(shù)據(jù)文件目錄
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/"
2. AOF
什么是 AOF
AOF 文件保存了 Redis 的數(shù)據(jù)庫(kù)狀態(tài)住涉, 而文件里面包含的都是符合 Redis 通訊協(xié)議格式的命令文本。
AOF 保存的模式
Redis 目前支持三種 AOF 保存模式钠绍,它們分別是:
-
AOF_FSYNC_NO
:不保存舆声。 -
AOF_FSYNC_EVERYSEC
:每一秒鐘保存一次。(生產(chǎn)中一般選這種) -
AOF_FSYNC_ALWAYS
:每執(zhí)行一個(gè)命令保存一次
不保存
在這種模式下柳爽, SAVE 只會(huì)在以下任意一種情況中被執(zhí)行:
Redis 被關(guān)閉
AOF 功能被關(guān)閉
系統(tǒng)的寫緩存被刷新(可能是緩存已經(jīng)被寫滿媳握,或者定期保存操作被執(zhí)行)
這三種情況下的 SAVE 操作都會(huì)引起 Redis 主進(jìn)程阻塞。
每執(zhí)行一個(gè)命令保存一次
在這種模式下磷脯,每次執(zhí)行完一個(gè)命令之后蛾找, WRITE 和 SAVE 都會(huì)被執(zhí)行。
另外赵誓,因?yàn)?SAVE 是由 Redis 主進(jìn)程執(zhí)行的打毛,所以在 SAVE 執(zhí)行期間,主進(jìn)程會(huì)被阻塞架曹,不能接受命令請(qǐng)求隘冲。
AOF 三種保存模式的比較
因?yàn)樽枞僮鲿?huì)讓 Redis 主進(jìn)程無法持續(xù)處理請(qǐng)求, 所以一般說來绑雄, 阻塞操作執(zhí)行得越少展辞、完成得越快, Redis 的性能就越好万牺。
模式 1 的保存操作只會(huì)在AOF 關(guān)閉或 Redis 關(guān)閉時(shí)執(zhí)行罗珍, 或者由操作系統(tǒng)觸發(fā), 在一般情況下脚粟, 這種模式只需要為寫入阻塞覆旱, 因此它的寫入性能要比后面兩種模式要高, 當(dāng)然核无, 這種性能的提高是以降低安全性為代價(jià)的: 在這種模式下扣唱, 如果運(yùn)行的中途發(fā)生停機(jī), 那么丟失數(shù)據(jù)的數(shù)量由操作系統(tǒng)的緩存沖洗策略決定团南。
模式 2 在性能方面要優(yōu)于模式 3 噪沙, 并且在通常情況下, 這種模式最多丟失不多于 2 秒的數(shù)據(jù)吐根, 所以它的安全性要高于模式 1 正歼, 這是一種兼顧性能和安全性的保存方案。
模式 3 的安全性是最高的拷橘, 但性能也是最差的局义, 因?yàn)榉?wù)器必須阻塞直到命令信息被寫入并保存到磁盤之后喜爷, 才能繼續(xù)處理請(qǐng)求。
綜合起來萄唇,三種 AOF 模式的操作特性可以總結(jié)如下:
模式 | WRITE 是否阻塞檩帐? | SAVE 是否阻塞? | 停機(jī)時(shí)丟失的數(shù)據(jù)量 | |
---|---|---|---|---|
AOF_FSYNC_NO |
阻塞 | 阻塞 | 操作系統(tǒng)最后一次對(duì) AOF 文件觸發(fā) SAVE 操作之后的數(shù)據(jù)穷绵。 | |
AOF_FSYNC_EVERYSEC |
阻塞 | 不阻塞 | 一般情況下不超過 2 秒鐘的數(shù)據(jù)轿塔。 | |
AOF_FSYNC_ALWAYS |
阻塞 | 阻塞 | 最多只丟失一個(gè)命令的數(shù)據(jù)特愿。 |
AOF 方式下的數(shù)據(jù)還原
Redis 讀取 AOF 文件并還原數(shù)據(jù)庫(kù)的詳細(xì)步驟如下:
創(chuàng)建一個(gè)不帶網(wǎng)絡(luò)連接的偽客戶端(fake client)仲墨。
讀取 AOF 所保存的文本,并根據(jù)內(nèi)容還原出命令揍障、命令的參數(shù)以及命令的個(gè)數(shù)目养。
根據(jù)命令、命令的參數(shù)和命令的個(gè)數(shù)毒嫡,使用偽客戶端執(zhí)行該命令癌蚁。
執(zhí)行 2 和 3 ,直到 AOF 文件中的所有命令執(zhí)行完畢兜畸。
完成第 4 步之后努释, AOF 文件所保存的數(shù)據(jù)庫(kù)就會(huì)被完整地還原出來。
注意咬摇, 因?yàn)?Redis 的命令只能在客戶端的上下文中被執(zhí)行伐蒂, 而 AOF 還原時(shí)所使用的命令來自于 AOF 文件, 而不是網(wǎng)絡(luò)肛鹏, 所以程序使用了一個(gè)沒有網(wǎng)絡(luò)連接的偽客戶端來執(zhí)行命令逸邦。
當(dāng)程序讀入這個(gè) AOF 文件時(shí), 它首先執(zhí)行 SELECT 0 命令 —— 這個(gè) SELECT 命令是由 AOF 寫入程序自動(dòng)生成的在扰, 它確保程序可以將數(shù)據(jù)還原到正確的數(shù)據(jù)庫(kù)上缕减。
注意:
為了避免對(duì)數(shù)據(jù)的完整性產(chǎn)生影響, 在服務(wù)器載入數(shù)據(jù)的過程中芒珠, 只有和數(shù)據(jù)庫(kù)無關(guān)的訂閱與發(fā)布功能可以正常使用桥狡, 其他命令一律返回錯(cuò)誤。
AOF 的重寫機(jī)制
為什么需要重寫機(jī)制
AOF 文件通過同步 Redis 服務(wù)器所執(zhí)行的命令皱卓, 從而實(shí)現(xiàn)了數(shù)據(jù)庫(kù)狀態(tài)的記錄裹芝, 但是, 這種同步方式會(huì)造成一個(gè)問題: 隨著運(yùn)行時(shí)間的流逝好爬, AOF 文件會(huì)變得越來越大局雄。
對(duì)同一個(gè)鍵的狀態(tài)的多次不同操作,而最終得到一個(gè)結(jié)果存炮。比如對(duì)列表的添加刪除元素炬搭。
被頻繁操作的鍵蜈漓。比如累加
重新機(jī)制是如何實(shí)現(xiàn)的
實(shí)際上, AOF 重寫并不需要對(duì)原有的 AOF 文件進(jìn)行任何寫入和讀取宫盔, 它針對(duì)的是數(shù)據(jù)庫(kù)中鍵的當(dāng)前值融虽,也就是源數(shù)據(jù)從目前的內(nèi)存中獲取。
考慮這樣一個(gè)情況灼芭, 如果服務(wù)器對(duì)鍵 list 執(zhí)行了以下四條命令:
RPUSH list 1 2 3 4 // [1, 2, 3, 4]
RPOP list // [1, 2, 3]
LPOP list // [2, 3]
LPUSH list 1 // [1, 2, 3]
那么當(dāng)前列表鍵 list 在數(shù)據(jù)庫(kù)中的值就為 [1, 2, 3] 有额。
如果我們要保存這個(gè)列表的當(dāng)前狀態(tài), 并且盡量減少所使用的命令數(shù)彼绷, 那么最簡(jiǎn)單的方式不是去 AOF 文件上分析前面執(zhí)行的四條命令巍佑, 而是直接讀取 list 鍵在數(shù)據(jù)庫(kù)的當(dāng)前值, 然后用一條 RPUSH 1 2 3 命令來代替前面的四條命令寄悯。
除了列表之外萤衰,集合、字符串猜旬、有序集脆栋、哈希表等鍵也可以用類似的方法來保存狀態(tài)。
根據(jù)鍵的類型洒擦, 使用適當(dāng)?shù)膶懭朊顏碇噩F(xiàn)鍵的當(dāng)前值椿争, 這就是 AOF 重寫的實(shí)現(xiàn)原理。
基本都步驟
for 遍歷所有數(shù)據(jù)庫(kù):
if 如果數(shù)據(jù)庫(kù)為空:
那么跳過這個(gè)數(shù)據(jù)庫(kù)
else:
寫入 SELECT 命令熟嫩,用于切換數(shù)據(jù)庫(kù)
for 選擇一個(gè)庫(kù)后秦踪,遍歷這個(gè)庫(kù)的所有鍵
if 如果鍵帶有過期時(shí)間,并且已經(jīng)過期邦危,那么跳過這個(gè)鍵
if 根據(jù)數(shù)據(jù)的類型洋侨,進(jìn)行相關(guān)操作。
AOF 重寫的實(shí)現(xiàn)方式
方式 | 區(qū)別 |
---|---|
bgrewriteaof 命令 |
不需要重啟服務(wù)倦蚪,不便于統(tǒng)一管理 |
配置文件實(shí)現(xiàn) | 需要重啟服務(wù)希坚,便于進(jìn)行統(tǒng)一管理 |
bgrewriteaof
配置文件實(shí)現(xiàn)
觸發(fā)條件,必須同時(shí)滿足如下條件
aof_current_size
和aof_base_size
可以通過命令info persistence
查看到
重寫流程圖
對(duì)于上圖有四個(gè)關(guān)鍵點(diǎn)補(bǔ)充一下:
在重寫期間陵且,由于主進(jìn)程依然在響應(yīng)命令裁僧,為了保證最終備份的完整性;因此它依然會(huì)寫入舊的AOF file中慕购,如果重寫失敗聊疲,能夠保證數(shù)據(jù)不丟失。當(dāng)然這個(gè)是可以通過配置來決定在重寫期間是否進(jìn)行主進(jìn)程普通的 AOF 操作沪悲。
為了把重寫期間響應(yīng)的寫入信息也寫入到新的文件中获洲,因此也會(huì)為子進(jìn)程保留一個(gè)buf,防止新寫的file丟失數(shù)據(jù)殿如。
重寫是直接把當(dāng)前內(nèi)存的數(shù)據(jù)生成對(duì)應(yīng)命令贡珊,并不需要讀取老的AOF文件進(jìn)行分析最爬、命令合并。
AOF文件直接采用的文本協(xié)議门岔,主要是兼容性好爱致、追加方便、可讀性高可認(rèn)為修改修復(fù)寒随。
注意:無論是RDB還是AOF都是先寫入一個(gè)臨時(shí)文件糠悯,然后通過 rename 完成文件的替換工作。
配置示例
// 要想使用 AOF 的全部功能妻往,需要設(shè)置為 yes
appendonly yes
// AOF 文件名互艾,路徑才看之前的 `dir` 配置項(xiàng)
appendfilename "appendonly.aof"
// 平常普通的 AOF 的策略
appendfsync everysec
// 當(dāng)執(zhí)行 AOF 重寫時(shí),是否繼續(xù)執(zhí)行平常普通的 AOF 操作蒲讯。
// 這里設(shè)置文件 yes , 表示不執(zhí)行
// 因?yàn)榧偃缤瑫r(shí)執(zhí)行灰署,兩種操作都會(huì)對(duì)磁盤 I/O 進(jìn)行訪問判帮,造成
// I/O 訪問量過大,產(chǎn)生性能衰減
no-appendfsync-on-rewrite yes
// AOF 文件容量的增長(zhǎng)率
auto-aof-rewrite-percentage 100
// AOF 文件的最低容量溉箕,就是當(dāng)前文件的大小大于此值時(shí)晦墙,就會(huì)進(jìn)行重寫。當(dāng)然這只是其中一個(gè)條件肴茄。
auto-aof-rewrite-min-size 64mb
添加鍵值對(duì)數(shù)據(jù)晌畅,觀察 AOF 文件
這里在命令行中設(shè)置吩谦,以便立刻生效
[root@s1 ~]# redis-cli
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
OK
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"
進(jìn)行簡(jiǎn)單的數(shù)據(jù)添加操作
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> set hello python
OK
127.0.0.1:6379> set hello redis
OK
127.0.0.1:6379> incr nums
(integer) 1
127.0.0.1:6379> incr nums
(integer) 2
127.0.0.1:6379> incr nums
(integer) 3
127.0.0.1:6379> incr nums
(integer) 4
127.0.0.1:6379> rpush li a
(integer) 1
127.0.0.1:6379> rpush li b
(integer) 2
127.0.0.1:6379> rpush li b
(integer) 3
127.0.0.1:6379> rpush li c
(integer) 4
127.0.0.1:6379> exit
查看 AOF 文件
[root@s1 ~]# head appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
SET
$5
hello
主動(dòng)觸發(fā)
先備份一份目前的 AOF 文件
[root@s1 ~]# cp /appendonly.aof{,.bak}
執(zhí)行命令 bgrewriteaof
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
最后對(duì)比兩個(gè)文件的內(nèi)容的不同之處蚪黑。
RDB 和 AOF
區(qū)別
如何抉擇
從服務(wù)器開啟 RDB
始終開啟 AOF
不要使用主機(jī)的全部?jī)?nèi)存