Redis 基礎(chǔ)部分

一、安裝

1. 官網(wǎng)下載源碼

image

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ù)

  1. /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ù)介紹參考這里

  1. 使用 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)聽
``

image
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ù)類型的基本介紹

image

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

image
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

image

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

image

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è)道理凛辣。

image

b. 什么情況下會(huì)觸發(fā) RDB

第一種情況,主動(dòng)執(zhí)行 save 命令(同步锁荔,阻塞 蟀给,就是save 命令執(zhí)行完畢后才能執(zhí)行后續(xù)的其他命令操作)

image

阻塞

image
保存 RDB 文件的策略

每次創(chuàng)建新的文件蝙砌,并且替換原來舊文件(假如存在舊的文件)

第二種情況阳堕,主動(dòng)執(zhí)行 bgsave 命令 (異步跋理,非阻塞 )

image
  • 文件策略和 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é)議格式的命令文本。

image

AOF 保存的模式

Redis 目前支持三種 AOF 保存模式钠绍,它們分別是:

  1. AOF_FSYNC_NO :不保存舆声。
  2. AOF_FSYNC_EVERYSEC :每一秒鐘保存一次。(生產(chǎn)中一般選這種)
  3. 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ì)變得越來越大局雄。

  1. 對(duì)同一個(gè)鍵的狀態(tài)的多次不同操作,而最終得到一個(gè)結(jié)果存炮。比如對(duì)列表的添加刪除元素炬搭。

  2. 被頻繁操作的鍵蜈漓。比如累加

重新機(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

image

配置文件實(shí)現(xiàn)

image
觸發(fā)條件,必須同時(shí)滿足如下條件
image

aof_current_sizeaof_base_size 可以通過命令 info persistence 查看到

重寫流程圖

image

對(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ū)別

image

如何抉擇

從服務(wù)器開啟 RDB

始終開啟 AOF

不要使用主機(jī)的全部?jī)?nèi)存

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市队橙,隨后出現(xiàn)的幾起案子拦坠,更是在濱河造成了極大的恐慌连躏,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贞滨,死亡現(xiàn)場(chǎng)離奇詭異入热,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)晓铆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門勺良,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人骄噪,你說我怎么就攤上這事尚困。” “怎么了链蕊?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵事甜,是天一觀的道長(zhǎng)忙芒。 經(jīng)常有香客問我,道長(zhǎng)讳侨,這世上最難降的妖魔是什么呵萨? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮跨跨,結(jié)果婚禮上潮峦,老公的妹妹穿的比我還像新娘。我一直安慰自己勇婴,他們只是感情好忱嘹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耕渴,像睡著了一般拘悦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上橱脸,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天础米,我揣著相機(jī)與錄音,去河邊找鬼添诉。 笑死屁桑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的栏赴。 我是一名探鬼主播蘑斧,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼须眷!你這毒婦竟也來了竖瘾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤花颗,失蹤者是張志新(化名)和其女友劉穎捕传,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捎稚,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乐横,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了今野。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片葡公。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖条霜,靈堂內(nèi)的尸體忽然破棺而出催什,到底是詐尸還是另有隱情,我是刑警寧澤宰睡,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布蒲凶,位于F島的核電站气筋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏旋圆。R本人自食惡果不足惜宠默,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望灵巧。 院中可真熱鬧搀矫,春花似錦、人聲如沸刻肄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)敏弃。三九已至卦羡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間麦到,已是汗流浹背绿饵。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留隅要,地道東北人蝴罪。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像步清,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子虏肾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一廓啊、安裝 1. 官網(wǎng)下載源碼 2. 安裝依賴包 3. 下載源碼包 3. 解壓安裝 4. 配置 redis 守護(hù)進(jìn)程...
    你笑的那么美丶閱讀 419評(píng)論 0 0
  • 一、安裝 1. 官網(wǎng)下載源碼 2. 安裝依賴包 3. 下載源碼包 3. 解壓安裝 4. 配置 redis 守護(hù)進(jìn)程...
    痕跡xxxyyyyyyY閱讀 562評(píng)論 0 0
  • 本文鏈接: http://www.reibang.com/p/2a9c21bfeca8 一封豪、安裝 1. 官網(wǎng)下載...
    運(yùn)維開發(fā)_西瓜甜閱讀 4,816評(píng)論 0 22
  • 一谴轮、安裝 1. 官網(wǎng)下載源碼 2. 安裝依賴包 3. 下載源碼包 3. 解壓安裝 4. 配置 redis 守護(hù)進(jìn)程...
    Lengfin閱讀 491評(píng)論 0 0
  • Redis是啥 Redis是一個(gè)開源的key-value存儲(chǔ)系統(tǒng),由于擁有豐富的數(shù)據(jù)結(jié)構(gòu)吹埠,又被其作者戲稱為數(shù)據(jù)結(jié)構(gòu)...
    一凡呀閱讀 1,174評(píng)論 0 5