詳解redis持久化儲存

2020-11-24 18:00:18

欄目介紹redis的持久化儲存。

推薦:

redis概述
REmote DIctionary Server(Redis)是一個基於key-value鍵值對的持久化資料庫儲存系統。redis和大名鼎鼎的Memcached快取服務軟體很像,但是redis支援的資料儲存型別比memcached更豐富,包括strings(字串),lists(列表),sets(集合)和sorted sets(有序集合)等。
這些資料型別支援push/pop,add/remove及取交集,並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached快取服務一樣,為了保證效率,資料都是快取在記憶體中提供服務。和memcached不同的是,redis持久化快取服務還會週期性的把更新的資料寫入到磁碟以及把修改的操作記錄追加到檔案裡記錄下來,比memcached更有優勢的是,redis還支援master-slave(主從)同步,這點很類似關係型資料庫MySQL主從複製功能。
Redis是一個開源的使用C語言編寫(3萬多行程式碼),支援網路,可基於記憶體亦可持久化的紀錄檔型,Key-Value資料庫,並提供多種語言的API。從2010年3月15日起,Redis的開發工作由VMware主持。
Redis軟體的出現,再一定程度上彌補了memcached這類key-value記憶體快取服務的不足,在部分場合可以對關聯式資料庫起到很好的補充作用。redis提供了Python,Ruby,Erlang,PHP使用者端,

1.2 redis特點

key-value鍵值型別儲存
支援資料可靠儲存及落地
單程序單執行緒高效能伺服器
crash safe & recovery slow
單機qps可以達到10W
適合小資料量高速讀寫存取

1.3 Redis優點

與memcached不同,Redis可以持久化儲存資料 效能很高:Redis能支援超過10W每秒的讀寫頻率。
豐富的資料型別:Redis支援二進位制的Strings,Lists,Hashes,Sets及sorted Sets等資料型別操作
原子:Redis的所有操作都是原子性的,同時Redis還支援對幾個操作全並後的原子性執行
豐富的特性:Redis還支援publish/subscribe(釋出/訂閱),通知,key過期等等特性。 redis支援異機主從複製。

1.4 redis缺陷與陷阱
系統執行有毛刺
不同命令延遲差別極大
記憶體管理開銷大(設定低於實體記憶體3/5)
buffer io造成系統OOM(記憶體溢位)

1.5 redis的資料型別
作為Key-value型儲存系統資料庫,Redis提供了鍵(Key)和值(value)對映關係。但是,除了常規的數值或字串,Redis的鍵值還可以是以下形式之一,下面為最為常用的資料型別:

String 字串
Hash 雜湊表
List 列表
Set 集合
Sorted set 有序集合

1.6 redis 持久化

通常,Redis將資料儲存於記憶體中,或被設定為使用虛擬記憶體。通過兩種方式可以實現資料持久化:使用快照(snapshot)的方式,將記憶體中的資料不斷寫入磁碟,或使用類似MySQL的binlog紀錄檔(aof但並不用於主從同步)方式,記錄每次更新的紀錄檔。前者效能較高,但是可能會引起一定程度的資料丟失;後者相反。

1.7 redis應用場景
redis的最佳應用場景

  • Redis最佳試用場景是全部資料in-memory
  • Redis更多場景是作為Memcached的替代品來使用。
  • 資料比較重要,對資料一致性有一定要求的業務。
  • 當需要除key/value之外的更多資料型別支援時,使用Redis更合適。
  • 需要提供主從同步以及負載均衡分散式應用場景(redis主從同步)

1.8redis生產上的教訓

一定要進行Master-slave主從同步設定,在出現服務故障時可以切換

在master禁用資料持久化,只需要在slave上設定資料持久化

實體記憶體+虛擬記憶體不足,這個時候dump一直死著,時間久了機器掛掉。這個情況就是災難!

當Redis實體記憶體使用超過記憶體總容量的3/5時就會開始比較危險了,就開始做swap,記憶體碎片大

當達到最大記憶體時,會清空帶有過期時間的key,即使key未到過期時間。

redis與DB同步寫的問題,先寫DB,後寫redis,因為寫記憶體基本上沒有問題。

快速部署一個redis環境
2.1 Redis部署環境搭建

主機名	eth0	用途
Master-redis01	10.0.0.135	主Redis
Slave-redis02	10.0.0.136	從Redis

2.2 開始安裝redis服務
在redis的官方網站(http://www.redis.io)下載最新的穩定版本redis。

wget -q http://download.redis.io/releases/redis-2.8.9.tar.gz

#在redis01和redis02都執行如下操作

[root@redis01 ~]# tar xf redis-2.8.9.tar -C /usr/src/
[root@redis01 ~]# cd /usr/src/redis-2.8.9/
[root@redis01 redis-2.8.9]# make MALLOC=jemalloc
[root@redis01 redis-2.8.9]# make PREFIX=/usr/local/redis install
[root@redis01 redis-2.8.9]# LANG=en
[root@redis01 redis-2.8.9]# tree /usr/local/redis/bin/
/usr/local/redis/bin/
├── redis-benchmark
├── redis-check-aof
├── redis-check-dump
├── redis-cli
└── redis-server

0 directories, 5 files

命令執行完成之後,會在/usr/local/redis/bin/目錄下生成5個可執行檔案,分別是:

redis-server,redis-cli,redis-benchmark,redis-check-aof,redis-check-dump

它們的作用如下:

redis-server    #Redis伺服器的daemon啟動程式
redis-cli       #Redis命令操作工具。當然,你也可以用telnet根據其純文字協定來操作
redis-benchmark #Redis效能測試工具,測試Redis在你的系統及你的設定下的讀寫效能。
redis-check-aof #對更新紀錄檔appendonly.aof檢查,是否可用,類似檢查mysql binlog的工具
redis-check-dump    #用於本地資料庫rdb檔案的檢查

2.3 設定並啟動redis服務
(1)設定啟動命令

操作過程:

[root@redis01 redis-2.8.9]# ln -s /usr/local/redis/bin/* /usr/local/bin/
(2)檢視命令幫助:

[root@redis01 redis-2.8.9]# redis-server -h
Usage: ./redis-server [/path/to/redis.conf] [options]
       ./redis-server - (read config from stdin)
       ./redis-server -v or --version
       ./redis-server -h or --help
       ./redis-server --test-memory <megabytes>

Examples:
       ./redis-server (run the server with default conf)
       ./redis-server /etc/redis/6379.conf
       ./redis-server --port 7777
       ./redis-server --port 7777 --slaveof 127.0.0.1 8888
       ./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:
       ./redis-server /etc/sentinel.conf --sentinel

(3)啟動redis服務

操作過程:

#從源程式目錄複製redis.conf到程式安裝目錄下

[root@redis01 redis-2.8.9]# cd /usr/src/redis-2.8.9/
[root@redis01 redis-2.8.9]# pwd
/usr/src/redis-2.8.9
[root@redis01 redis-2.8.9]# mkdir /usr/local/redis/conf
[root@redis01 redis-2.8.9]# cp redis.conf /usr/local/redis/conf/

#啟動redis服務

[root@redis01 redis-2.8.9]# redis-server /usr/local/redis/conf/redis.conf &

#檢視redis程序啟動情況

[root@redis01 redis-2.8.9]# ps -ef | grep redis | grep -v grep
root       3169   1288  0 10:17 pts/0    00:00:00 redis-server *:6379

特別提示:

redis啟動成功後,在最後會出現如下警示資訊:

[3169] 02 Oct 10:17:30.689 # Server started, Redis version 2.8.9
[3169] 02 Oct 10:17:30.690 # 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.
[3169] 02 Oct 10:17:30.690 * The server is now ready to accept connections on port 6379

#警示大概意思為:
overcommit_memory被設定為了0.如果記憶體不夠的情況下後臺儲存可能會失敗;要解決這個問題,需要在/etc/sysctl.conf組態檔中將vm.overcommit_memory設定為1;或者通過命令「sysctl vm.overcommit_memory=1」來修改。
因此,我們做一下處理後在啟動redis程序

[root@redis01 redis-2.8.9]# pkill redis
[root@redis01 redis-2.8.9]# sysctl vm.overcommit_memory=1
vm.overcommit_memory = 1
[root@redis01 redis-2.8.9]# redis-server /usr/local/redis/conf/redis.conf &

經過處理後,再啟動redis就沒有任何警告了。
vm.overcommit_memory引數說明:
根據核心檔案,該引數有三個值,分別是:
0:當使用者空間請求更多的記憶體時,核心嘗試估算出剩餘可用的記憶體。
1:當設這個引數值為1時,核心允許超量使用記憶體直到用完為止,主要用於科學計算
2:當設這個引數值為2時,核心會使用一個絕不過量使用記憶體的演演算法,即系統整個記憶體地址空間不能超過swap+50%的RAM值,50%引數的設定是在overcommit_ratio中設定。

測試關閉redis服務的命令

redis-cli shutdown 關閉redis程序

[root@redis01 redis-2.8.9]# ps -ef | grep redis | grep -v grep
root       3200   1288  0 10:38 pts/0    00:00:08 redis-server *:6379                          
[root@redis01 redis-2.8.9]# redis-cli shutdown
[3200] 02 Oct 12:43:46.621 # User requested shutdown...
[3200] 02 Oct 12:43:46.621 * Saving the final RDB snapshot before exiting.
[3200] 02 Oct 12:43:46.630 * DB saved on disk
[3200] 02 Oct 12:43:46.631 # Redis is now ready to exit, bye bye...
[1]+  Done                    redis-server /usr/local/redis/conf/redis.conf
[root@redis01 redis-2.8.9]# ps -ef | grep redis | grep -v grep
[root@redis01 redis-2.8.9]# redis-server /usr/local/redis/conf/redis.conf

redis自啟動指令碼

[root@ser02 redis]# vim redserver.sh
#!/bin/bash
stop(){
/data/redis/bin/redis-cli -a redis shutdown
}
start(){
/data/redis/bin/redis-server /data/redis/conf/redis.conf &
}
conn(){
/data/redis/bin/redis-cli -a redis
}
case $1 in
   start)
   start
   ;;
   stop)
   stop
   ;;
   restart)
   stop
   start
   ;;
   conn)
   conn
   ;;
   *)
   echo "Usage:$0 (start|stop|restart)"
esac
[root@ser02 redis]# chmod +x redserver.sh 
[root@ser02 redis]# vim /etc/profile
export PATH=/data/redis/:$PATH
[root@ser02 redis]# source /etc/profile

redserver.sh  start ##開啟redis服務

redserver.sh conn ##登入redis
2.4 通過使用者端操作redis資料庫
下面我們來簡單操作一下資料庫。
插入資料:設定一個key-value對

[root@redis01 redis-2.8.9]# redis-cli   #通過使用者端連線本地redis 
127.0.0.1:6379> set id 001  #寫入一條資料key(id),value(001)
OK
127.0.0.1:6379> get id  #取值key(id)
"001"   #顯示key對應的值
127.0.0.1:6379> del id  #刪除key(id)
(integer) 1     #1表示成功
127.0.0.1:6379> exists id   #驗證key是否存在
(integer) 0     #0表示不存在
127.0.0.1:6379> get id  #取key的值
(nil)           #報錯資訊
127.0.0.1:6379> set user001 benet
OK
127.0.0.1:6379> set user002 yunjisuan
OK
127.0.0.1:6379> set user003 yun123
OK
127.0.0.1:6379> get user001
"benet"
127.0.0.1:6379> get user002
"yunjisuan"
127.0.0.1:6379> keys *  #檢視redis裡所有的key
1) "user003"
2) "user002"
3) "user001"

更多操作方式及命令幫助

(1)redis資料庫的表模式

127.0.0.1:6379> keys *  #檢視所有key
1) "user003"
2) "user002"
3) "user001"
127.0.0.1:6379> select 1    #切換到表1模式
OK
127.0.0.1:6379[1]> keys *   #查詢所有key
(empty list or set)     #什麼都沒有
127.0.0.1:6379[1]> set name wangwu  #寫入一個key-value對
OK
127.0.0.1:6379[1]> keys *   #檢視所有key
1) "name"           #key(name)已經有了
127.0.0.1:6379[1]> get name #檢視key(name)的值
"wangwu"
127.0.0.1:6379[1]> select 0 #切換回表0模式(初始模式)
OK
127.0.0.1:6379> keys *      #檢視所有key
1) "user003"
2) "user002"
3) "user001"

(2)redis-cli使用者端的遠端連線及非互動式運算元據庫

[root@redis01 redis-2.8.9]# redis-cli -h 10.0.0.135 -p 6379
10.0.0.135:6379> quit
[root@redis01 redis-2.8.9]# redis-cli -h 10.0.0.135 -p 6379 set aaa 111
OK
[root@redis01 redis-2.8.9]# redis-cli -h 10.0.0.135 -p 6379 get aaa
"111"

redis安全
(1)為redis使用者端設定外部連結密碼

警告:
因為redis速度相當快,所以在一臺比較好的伺服器下,一個外部的使用者可以在1秒內進行上萬次的密碼嘗試,這意味著你需要指定非常非常強大的密碼來防止暴力破解。
設定密碼:

[root@ser02 bin]# vim /data/redis/conf/redis.conf 
 requirepass redis

(2)將危險的命令改名
rename-command set 「sset」 #將set改名為sset

為php安裝redis使用者端擴充套件
(1)獲取原始碼包

wget https://github.com/nicolasff/phpredis/archive/master.zip

(2)安裝

[root@redis01 ~]# ls -l phpredis-master.tar.gz 
-rw-r--r--. 1 root root 164509 Oct  2 19:23 phpredis-master.tar.gz
[root@redis01 ~]# tar xf phpredis-master.tar.gz -C /usr/src/
[root@redis01 ~]# cd /usr/src/phpredis-master/
[root@redis01 phpredis-master]# /usr/local/php/bin/phpize
[root@redis01 phpredis-master]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@redis01 phpredis-master]# make && make install

vim /etc/php.ini
	extensions = /usr/lib64/php/modules/redis.so
	[root@ser02 modules]# systemctl restart httpd

測試:

[root@ser02 redis]# cd /var/www/html/
	[root@ser02 html]# vim 1.php 
	<?php
  	$redis = new Redis();
  	$redis -> connect("192.168.25.151",4423);
  	$redis -> auth("redis");
  	$redis -> set("name","anliu");
  	$var = $redis -> get("name");
 	echo "$var";
	?>
	[root@ser02 html]# systemctl restart httpd

	
	[root@ser02 html]# php 1.php 
	anliu

安裝Python redis使用者端操作redis

wget https://pypi.python.org/packages/source/r/redis/redis-2.10.1.tar.gz
tar xf redis-2.10.1.tar.gz
cd redis-2.10.1
python setup.py install

開發python程式操作redis

在操作前請將之前redis組態檔裡修改的redis命令註釋掉,否則報錯

[root@redis01 redis-2.10.1]# python
Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import redis        #參照redis支援庫
>>> r = redis.Redis(host='10.0.0.135',port='6379',password='yunjisuan') #建立redis資料庫的連線物件(物件導向方式)
>>> r.set('name','benet')   #操作物件呼叫set方法寫入資料
True
>>> r.get('name')           #操作物件呼叫get方式讀取資料
'benet'
>>> r.dbsize()              #操作物件檢視redis資料庫的資料條數
1L
>>> r.keys()                #檢視所有的key
['name']
>>> exit()                  #退出

2.11 通過Web介面連線Python程式展示redis
開發Python指令碼

[root@redis01 scripts]# cat python-redis.py 
#/usr/bin/python

from wsgiref.simple_server import make_server
import redis

def get_redis():
    r = redis.Redis(host='10.0.0.135',port='6379',password='yunjisuan',db=0)
    r.set('name','yunyunyun')
    return r.get('name')
    
def hello_world_app(environ,start_response):
    status = '200 OK'   #HTTP Status
    headers = [('Content-type','text/plain')]   #HTTP Headers
    start_response(status,headers)
    
    # The returned object is going to be printed
    return get_redis()

httpd = make_server('',8000,hello_world_app)
print "Serving on port 8000..."

# Server until process is killed
httpd.serve_forever()

啟動python指令碼

注意關閉iptables

[root@redis01 scripts]# python python-redis.py 
Serving on port 8000...     #監聽8000埠

在這裡插入圖片描述

以上就是詳解redis持久化儲存的詳細內容,更多請關注TW511.COM其它相關文章!