詳解redis持久化存儲

redis數據庫教程欄目介紹redis的持久化存儲。

詳解redis持久化存儲

推薦: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提供了pythonrubyerlangphp客戶端,

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 &amp;

經過處理后,再啟動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持久化存儲

? 版權聲明
THE END
喜歡就支持一下吧
點贊5 分享