redis
一、redis介紹
1.redis服務介紹
Remote Dictionary Server(Redis)是一個基於key-value鍵值對的持久化數據庫存儲系統。redis和大名鼎鼎的Memcached緩存服務很像,但是redis支持的數據存儲類型更豐富,包括string(字符串)、list(鏈表)、set(集合)和zset(有序集合)等。
這些數據類型都支持push/pop、add/remove及取交集、並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached緩存服務一樣,爲了保證效率,數據都是緩存在內存中提供服務。和memcached不同的是,redis持久化緩存服務器還會週期性的把更新的數據寫入到磁盤以及把修改的操作記錄追加到文件裏記錄下來,比memcached更有優勢的是,redis還支持master-slave(主從)同步,這點很類似關係型數據庫MySQL。
官方文檔:http://www.redis.io/documentation
2.redis的優點
與memcached不同,可以持久化存儲數據
性能很高:Redis能支持超過100K每秒的讀寫頻率
豐富的數據類型:Strings,Lists,Hashes,Sets,Ordered Sets等
原子:Redis的所有操作都是原子性的,同時Redis還支持對幾個操作全並後的原子性執行
豐富的特性:Redis還支持publish/subscribe,通知,key過期等特性
redis支持主從複製
3.redis的數據類型
Redis最爲常用的數據類型主要有下:
String
Hash
List
Set
Sorted set
4.redis應用場景
傳統的mysql+memcached的網站架構遇到的問題:
mysql數據庫實際上是適合進行海量數據存儲的,加上通過memcached將熱點數據存放到內存cache裏,達到加速數據訪問的目的,絕大部分公司都曾經使用過這樣的架構,但隨着業務數據量的不斷增加,和訪問量的持續增長,很多問題就會暴露出來:
(1)需要不斷對mysql進行拆庫拆表,memcached也需不斷跟着擴容,擴容和維護工作佔據大量開發運維時間。
(2)memcached與mysql數據庫數據一致性問題是個難題。
(3)memcached數據命中率低或down機,會導致大量訪問直接穿透到數據庫,導致mysql無法支撐訪問。
(4)誇機房cache同步一致性問題。
redis最佳應用場景:
(1)redis最佳適用場景是全部數據in-memory
(2)redis更多場景是作爲memcached的替代品來使用
(3)支持持久化
(4)當需要key/value之外的更多數據類型支持時,使用redis更合適
(5)需要負載均衡場景(redis主從同步)
二、redis安裝部署
1.redis安裝
wget wget http://download.redis.io/releases/redis-2.8.9.tar.gz
[root@redis ~]# tar xf redis-2.8.9.tar.gz
[root@redis ~]# cd redis-2.8.9
[root@redis redis-2.8.9]# make MALLOC=jemalloc
[root@redis redis-2.8.9]# make PREFIX=/usr/local/redis-2.8.9 install
[root@redis redis-2.8.9]# ln -s /usr/local/redis-2.8.9/ /usr/app/redis
[root@redis bin]# ll /usr/app/redis/bin/
total 9140
-rwxr-xr-x. 1 root root 4589115 Dec 8 19:31 redis-benchmark
-rwxr-xr-x. 1 root root 22177 Dec 8 19:31 redis-check-aof
-rwxr-xr-x. 1 root root 45395 Dec 8 19:31 redis-check-dump
-rwxr-xr-x. 1 root root 4693266 Dec 8 19:31 redis-cli
lrwxrwxrwx. 1 root root 12 Dec 8 19:31 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 0 Dec 8 19:33 redis-server
redis-server:redis服務器的daemon啓動程序
redis-cli:redis命令行操作工具
redis-benchmark:redis性能測試工具,測試redis在系統及配置下的讀寫性能
redis-check-aof:更新日誌檢查
redis-check_dump:用戶本地數據庫檢查
export PATH=$PATH:/usr/app/redis/bin/
./etc/profile
啓動redis服務
mkdir /usr/app/redis/conf
[root@redis ~]# cp redis-2.8.9/redis.conf /usr/app/redis/conf/
[root@redis ~]# sysctl vm.overcommit_memory=1
vm.overcommit_memory = 1
overcommit_memory文件指定了內核針對內存分配的策略,其值可以是0、1、2。
0, 表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。
1, 表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。
2, 表示內核允許分配超過所有物理內存和交換空間總和的內存
[root@redis ~]# /usr/app/redis/bin/redis-server /usr/app/redis/conf/redis.conf &
[2] 14204
[root@redis ~]# [14204] 08 Dec 20:38:27.551 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 2.8.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in stand alone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 14204
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
[14204] 08 Dec 20:38:27.554 # Server started, Redis version 2.8.9
[14204] 08 Dec 20:38:27.554 * The server is now ready to accept connections on port 6379
[root@redis ~]#
[root@redis bin]# redis-cli -h 192.168.51.91 -p 6379 set ll001 gongyi
OK
[root@redis bin]# redis-cli get ll001
"gongyi"
[root@redis bin]# redis-cli del ll001
(integer) 1
[root@redis bin]# redis-cli get ll001
(nil)
redis的php客戶端擴展安裝
wget https://github.com/nicolasff/phpredis/archive/master.zip
unzip master.zip
cd phpredis-master/
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install
vim php.ini,重啓php
export "extension = redis.so" >> /usr/local/php/lib/php.ini
2.redis主從同步
部署從庫
189 ################################# REPLICATION #################################
190
191 # Master-Slave replication. Use slaveof to make a Redis instance a copy of
192 # another Redis server. Note that the configuration is local to the slave
193 # so for example it is possible to configure the slave to save the DB with a
194 # different interval, or to listen to another port, and so on.
195 #
196 # slaveof <masterip> <masterport>
197 slaveof 192.168.51.91 6379
[root@gong conf]# redis-server /usr/app/redis/conf/redis.conf &
[37997] 04 Dec 19:37:10.427 # Server started, Redis version 2.8.9
[37997] 04 Dec 19:37:10.427 * The server is now ready to accept connections on port 6379
[37997] 04 Dec 19:37:10.427 * Connecting to MASTER 192.168.51.91:6379
[37997] 04 Dec 19:37:10.428 * MASTER <-> SLAVE sync started
[37997] 04 Dec 19:37:10.438 * Non blocking connect for SYNC fired the event.
[37997] 04 Dec 19:37:10.439 * Master replied to PING, replication can continue...
[37997] 04 Dec 19:37:10.442 * Partial resynchronization not possible (no cached master)
[37997] 04 Dec 19:37:10.444 * Full resync from master: 6f61266ae06d12b66527a008731663e5cd70e89e:1
[37997] 04 Dec 19:37:10.575 * MASTER <-> SLAVE sync: receiving 159 bytes from master
[37997] 04 Dec 19:37:10.575 * MASTER <-> SLAVE sync: Flushing old data
[37997] 04 Dec 19:37:10.575 * MASTER <-> SLAVE sync: Loading DB in memory
[37997] 04 Dec 19:37:10.575 * MASTER <-> SLAVE sync: Finished with success
從庫監控,並往主庫寫key/value
[root@redis-slave conf]# redis-cli -h localhost -p 6379 monitor
OK
1449229161.982676 [0 192.168.51.91:6379] "PING"
1449229167.489080 [0 192.168.51.91:6379] "set" "jj001" "xxxxxxxxxx"
1449229172.905278 [0 192.168.51.91:6379] "PING"
[root@redis-master ~]# redis-cli
127.0.0.1:6379> set jj001 xxxxxxxxxx
OK
127.0.0.1:6379>
[root@redis-slave conf]# redis-cli -h localhost -p 6379 get jj001
"xxxxxxxxxx"
[root@redis-slave conf]#
3.redis故障轉移
wget http://www.keepalived.org/software/keepalived-1.2.7.tar.gz
tar xf keepalived-1.2.7.tar.gz
cd keepalived-1.2.7
./configure
報錯
checking for poptGetContext in -lpopt... no
configure: error: Popt libraries is required
[root@redis-master keepalived-1.2.7]# echo $?
1
通過yum list all查找popt包名,然後安裝
[root@redis-master keepalived-1.2.7]# yum list all|grep popt
popt.x86_64 1.13-7.el6 @anaconda-CentOS-201410241409.x86_64/6.6
popt.i686 1.13-7.el6 base
popt-devel.i686 1.13-7.el6 base
popt-devel.x86_64 1.13-7.el6 base
popt-static.x86_64 1.13-7.el6 base
yum install popt-devel -y
./configure
config.status: creating keepalived/libipvs-2.6/Makefile
Keepalived configuration
------------------------
Keepalived version : 1.2.7
Compiler : gcc
Compiler flags : -g -O2
Extra Lib : -lpopt -lssl -lcrypto
Use IPVS Framework : Yes
IPVS sync daemon support : Yes
IPVS use libnl : No
Use VRRP Framework : Yes
Use VRRP VMAC : Yes
SNMP support : No
Use Debug flags : No
[root@redis-master keepalived-1.2.7]# echo $?
0
make && make install
初始化keepalived,拷貝啓動腳本,配置文件等
cp /usr/local/etc/rc.d/init.d/keepalived /etc/init.d/
cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived
cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/sbin/keepalived /usr/sbin/
keepalived master配置文件
global_defs {
notification_email {
}
notification_email_from [email protected]
smtp_server smtp.163.com
smtp_connect_timeout 30
router_id nginx_master
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.54.244
}
}
keepalived backup配置文件
global_defs {
notification_email {
}
notification_email_from [email protected]
smtp_server smtp.163.com
smtp_connect_timeout 30
router_id nginx_backup
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.54.244
}
}
keep1和keep2啓動服務
/etc/init.d/keepalived start
查看VIP在master上
[root@redis-master keepalived-1.2.7]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:99:f2:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.51.91/23 brd 192.168.51.255 scope global eth0
inet 192.168.51.244/32 scope global eth0
inet6 fe80::20c:29ff:fe99:f2f7/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
4.DOWN機測試
通過VIP存取key/value
[root@redis-slave keepalived-1.2.7]# redis-cli -h 192.168.51.244 set vip001 tttttttttttt
OK
[root@redis-slave keepalived-1.2.7]# redis-cli -h 192.168.51.244 get vip001
"tttttttttttt"
master本地取值
[root@redis-master keepalived-1.2.7]# redis-cli -h localhost
localhost:6379> get vip001
"tttttttttttt"
localhost:6379>
slave本地取值
[root@redis-slave keepalived-1.2.7]# redis-cli -h localhost get vip001
"tttttttttttt"
模擬master down機
將master虛擬機電源關閉
slave上ip a查看VIP
[root@redis-slave keepalived-1.2.7]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:a9:83:80 brd ff:ff:ff:ff:ff:ff
inet 192.168.51.112/23 brd 192.168.51.255 scope global eth0
inet 192.168.51.244/32 scope global eth0
inet6 fe80::20c:29ff:fea9:8380/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
VIP漂移到slave,並從slave讀數據完成
[root@redis-slave keepalived-1.2.7]# redis-cli -h 192.168.51.244 get vip001
"tttttttttttt"