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 {

     18054095509@163.com

   }

   notification_email_from 18054095509@qq.com

   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 {

        18054095509@163.com

   }

   notification_email_from 18054095509@163.com

   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"