标签为 Redis 的文章

通过Keepalived实现Redis Failover自动故障切换功能[实践分享]

参考资料:
http://patrick-tang.blogspot.com/2012/06/redis-keepalived-failover-system.html
http://deidara.blog.51cto.com/400447/302402

背景介绍:
目前,Redis还没有一个类似于MySQL Proxy或Oracle RAC的官方HA方案。
Redis作者有一个名为Redis Sentinel的计划(http://redis.io/topics/sentinel),据称将会有监控,报警和自动故障转移三大功能,非常不错。
但可惜的是短期内恐怕还不能开发完成。

因此,如何在出现故障时自动转移是一个需要解决的问题。

通过对网上一些资料的搜索,有建议采用HAProxy或Keepalived来实现的,事实上如果是做Failover而非负载均衡的话,Keepalived的效率肯定是超过HAProxy的,所以我决定采用Keepalived的方案。

环境介绍:
Master: 10.6.1.143
Slave: 10.6.1.144
Virtural IP Address (VIP): 10.6.1.200

设计思路:
当 Master 与 Slave 均运作正常时, Master负责服务,Slave负责Standby;
当 Master 挂掉,Slave 正常时, Slave接管服务,同时关闭主从复制功能;
当 Master 恢复正常,则从Slave同步数据,同步数据之后关闭主从复制功能,恢复Master身份,于此同时Slave等待Master同步数据完成之后,恢复Slave身份。
然后依次循环。

需要注意的是,这样做需要在Master与Slave上都开启本地化策略,否则在互相自动切换的过程中,未开启本地化的一方会将另一方的数据清空,造成数据完全丢失。

下面,是具体的实施步骤:

在Master和Slave上安装Keepalived
$ sudo apt-get install keepalived

修改Master和Slave的/etc/hosts文件
$ sudo vim /etc/hosts

127.0.0.1	localhost
10.6.1.143	redis
10.6.1.144	redis-slave

默认安装完成keepalived之后是没有配置文件的,因此我们需要手动创建:

首先,在Master上创建如下配置文件:
$ sudo vim /etc/keepalived/keepalived.conf

vrrp_script chk_redis { 
                script "/etc/keepalived/scripts/redis_check.sh"   ###监控脚本 
                interval 2                                        ###监控时间 
} 
vrrp_instance VI_1 { 
        state MASTER                            ###设置为MASTER
        interface eth0                          ###监控网卡    
        virtual_router_id 51
        priority 101                            ###权重值
        authentication { 
                     auth_type PASS             ###加密 
                     auth_pass redis            ###密码 
        } 
        track_script { 
                chk_redis                       ###执行上面定义的chk_redis
        } 
        virtual_ipaddress { 
             10.6.1.200                         ###VIP 
        }
        notify_master /etc/keepalived/scripts/redis_master.sh
        notify_backup /etc/keepalived/scripts/redis_backup.sh
        notify_fault  /etc/keepalived/scripts/redis_fault.sh
        notify_stop   /etc/keepalived/scripts/redis_stop.sh 
} 

然后,在Slave上创建如下配置文件:
$ sudo vim /etc/keepalived/keepalived.conf

vrrp_script chk_redis { 
                script "/etc/keepalived/scripts/redis_check.sh"   ###监控脚本 
                interval 2                                        ###监控时间 
} 
vrrp_instance VI_1 { 
        state BACKUP                                ###设置为BACKUP 
        interface eth0                              ###监控网卡
        virtual_router_id 51 
        priority 100                                ###比MASTRE权重值低 
        authentication { 
                     auth_type PASS 
                     auth_pass redis                ###密码与MASTRE相同
        } 
        track_script { 
                chk_redis                       ###执行上面定义的chk_redis
        } 
        virtual_ipaddress { 
             10.6.1.200                         ###VIP 
        } 
        notify_master /etc/keepalived/scripts/redis_master.sh
        notify_backup /etc/keepalived/scripts/redis_backup.sh
        notify_fault  /etc/keepalived/scripts/redis_fault.sh
        notify_stop   /etc/keepalived/scripts/redis_stop.sh 
}

阅读全文 »

, ,

34 Comments

Redis持久化实践及灾难恢复模拟

参考资料:
Redis Persistence http://redis.io/topics/persistence
Google Groups https://groups.google.com/forum/?fromgroups=#!forum/redis-db

一、对Redis持久化的探讨与理解

目前Redis持久化的方式有两种: RDB 和 AOF

首先,我们应该明确持久化的数据有什么用,答案是用于重启后的数据恢复。
Redis是一个内存数据库,无论是RDB还是AOF,都只是其保证数据恢复的措施。
所以Redis在利用RDB和AOF进行恢复的时候,都会读取RDB或AOF文件,重新加载到内存中。

RDB就是Snapshot快照存储,是默认的持久化方式。
可理解为半持久化模式,即按照一定的策略周期性的将数据保存到磁盘。
对应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期。
下面是默认的快照设置:

save 900 1    #当有一条Keys数据被改变时,900秒刷新到Disk一次
save 300 10   #当有10条Keys数据被改变时,300秒刷新到Disk一次
save 60 10000 #当有10000条Keys数据被改变时,60秒刷新到Disk一次

Redis的RDB文件不会坏掉,因为其写操作是在一个新进程中进行的。
当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,然后通过原子性rename系统调用将临时文件重命名为RDB文件。
这样在任何时候出现故障,Redis的RDB文件都总是可用的。

同时,Redis的RDB文件也是Redis主从同步内部实现中的一环。
第一次Slave向Master同步的实现是:
Slave向Master发出同步请求,Master先dump出rdb文件,然后将rdb文件全量传输给slave,然后Master把缓存的命令转发给Slave,初次同步完成。
第二次以及以后的同步实现是:
Master将变量的快照直接实时依次发送给各个Slave。
但不管什么原因导致Slave和Master断开重连都会重复以上两个步骤的过程。
Redis的主从复制是建立在内存快照的持久化基础上的,只要有Slave就一定会有内存快照发生。
阅读全文 »

7 Comments

内存优化之Redis数据结构的设计优化实践[原创分享]

参考资料:
http://www.mysqlops.com/2011/09/06/redis-kv-design.html
http://blog.nosqlfan.com/html/3379.html

通过对文章《节约内存:Instagram的Redis实践》的阅读之后,感觉受益不少。
在文章中,Instagram 通过对数据结构的设计优化,使内存从之前的21GB逐步降低到15GB,5GB最后到达了3GB,效果非常显著。

因此自己打算在测试环境中模拟其思路,通过实践加深理解并得出一些真实的数据。

首先,需要生成一些数据,为了方便理解,我从本地CloudStack中的vm_instance表中取了一些数据。
下面我们来看一个关系型数据库的设计:

mysql> select id,instance_name,private_ip_address,uuid,created from vm_instance;
+----+---------------+--------------------+--------------------------------------+---------------------+
| id | instance_name | private_ip_address | uuid                                 | created             |
+----+---------------+--------------------+--------------------------------------+---------------------+
|  1 | s-1-VM        | 10.6.59.6          | 8c252255-82b8-4934-830e-0573cc9e0a1c | 2012-05-27 04:06:54 |
|  2 | v-2-VM        | 10.6.88.209        | 1aae6ab9-73cb-46e3-aafb-985f6a143a08 | 2012-05-27 04:06:54 |
|  4 | r-4-VM        | 169.254.1.42       | 5520f0e9-4c5a-4599-be5c-0ea74b59d6dd | 2012-05-27 10:45:42 |
|  5 | i-2-5-VM      | 10.6.8.55          | 2191b464-58be-423d-9863-ce9c0397fc67 | 2012-05-27 11:10:06 |
|  6 | i-2-6-VM      | 10.6.8.56          | c5be506a-aaae-475a-beb7-e6af2a33c8d3 | 2012-05-28 02:07:55 |

下面我们采用Redis作为数据库,首先需要将关系型数据转化为Key/Value数据。
可采用如下的方式来实现:
Key --> 表名:主键值:列名
Value --> 列值

使用冒号作为分隔符,目前算是一个不成文的规矩。例如工具php-admin for redis就是默认以冒号分割的。
下面我以前五行数据为例,数据转化的命令如下:
阅读全文 »

1 Comment

Redis的编译安装与配置

参考资料:
http://heyheymymy.net/python/install-redis-in-ubuntu-10-04
http://www.cnblogs.com/hb_cattle/archive/2011/10/22/2220907.html

Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。有字符串,链表,集合和有序集合。支持在服务器端计算集合的并,交和补集(difference)等,还支持多种排序功能。所以Redis也可以被看成是一个数据结构服务器。
Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。

1. 安装Redis Server
安装系统所需软件包
$ sudo apt-get install python-setuptools python-dev build-essential python-pip libcurl4-openssl-dev

安装libunwind库
$ wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz
$ tar zxvf libunwind-0.99-alpha.tar.gz
$ cd libunwind-0.99-alpha/
$ CFLAGS=-fPIC ./configure
$ make CFLAGS=-fPIC
$ sudo make CFLAGS=-fPIC install

安装google-preftools
$ wget http://google-perftools.googlecode.com/files/google-perftools-1.8.1.tar.gz
$ tar zxvf google-perftools-1.8.1.tar.gz
$ cd google-perftools-1.8.1/
$ ./configure --disable-cpu-profiler --disable-heap-profiler --disable-heap-checker --disable-debugalloc --enable-minimal
$ sudo make && make install
$ sudo echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
$ sudo /sbin/ldconfig

$ wget http://redis.googlecode.com/files/redis-2.4.17.tar.gz
$ tar xzf redis-2.4.17.tar.gz
$ cd redis-2.4.17
$ sudo mkdir -p /opt/redis
$ sudo make PREFIX=/opt/redis USE_TCMALLOC=yes install

$ sudo lsof -n | grep tcmalloc
redis-ser 31590 elton mem REG 8,3 1155539 4856411 /usr/local/lib/libtcmalloc_minimal.so.0.2.1

$ tree /opt/redis
/opt/redis
├── bin
├── redis-benchmark #性能测试工具,测试Redis在你的系统及你的配置下的读写性
├── redis-check-aof #更新日志检查
├── redis-check-dump #用于本地数据库检查
├── redis-cli #命令行操作工具
└── redis-server #Redis服务器的daemon启动程序

2. 创建服务管理脚本
$ sudo vim /etc/init.d/redis

#!/bin/sh

PATH="/opt/redis/bin:$PATH"
EXEC="/opt/redis/bin/redis-server"
CLIEXEC="/opt/redis/bin/redis-cli"
PIDFILE="/opt/redis/run/redis_6379.pid"
CONF="/opt/redis/etc/redis_6379.conf"
REDISPORT="6379"

case "$1" in
    start)
        if [ -f $$PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed."
        else
                echo "Starting Redis server..."
                $EXEC $CONF
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running."
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
                $CLIEXEC -p $REDISPORT shutdown
                while [ -x /proc/${PID} ]
                do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped."
        fi
        ;;
    *)    
        echo "Usage: $0 {start|stop}" >&2
        exit 1
        ;;
esac

3. 创建与修改配置文件
阅读全文 »

3 Comments