Redis HA架构:Redis(master/slave) + Keepalived + Redis Sentinel + Twemproxy + Twemproxy Agent

一、Redis HA架构描述:
目前,Redis高可用方案,主要集中于以下几种:
1.Redis(master/slave)
2.Redis(master/slave) + Keepalived + Redis Sentinel
3.Codis
4.Redis(master/slave) + Keepalived + Redis Sentinel + Twemproxy + Keepalived
5.Redis(master/slave) + Keepalived + Redis Sentinel + Twemproxy + Twemproxy Agent + nodejs +npm
第 4 种,我们通过 两个keepalived 来是实现HA,一个是实现Redis HA的vip ;一个是Twemproxy HA的VIP
第 5 种,使用一个 keepalived 来实现Twemproxy HA,通过 Twemproxy Agent 来更新 Twemproxy 配置(当redis主从切换时)
下面,我们主要讲解第 5 种 方案:
Redis(master/slave) + Keepalived + Redis Sentinel + Twemproxy + Twemproxy Agent + nodejs + nodejs-forever-agent + npm

二、Redis HA架构图:

Image

三、Redis(master/slave) + Redis Sentinel 部署:
具体的安装可以参照:
Redis HA 下的
20141202:Redis 主从部署
20150421:Redis Sentinel + keepalived 部署
下面,将简单描述:
1.Redis(master/slave) 的部署:[ 部署在 10.55、10.56 ]
10.55、10.56 都部署两套Redis,
# 第二套redis,只要将配置文件( redis.conf) 复制并改名为 redis_6380.conf
# 新配置文件/ 启动脚本等 修改,参照 Redis 主从部署一篇
2.Redis Sentinel 部署:[ 部署在 10.54、10.55、10.56 ]
# 只要在Redis Sentinel 的配置文件,把新建的Redis master 添加进去,就可;
# 具体,参照如下文件:
vim /usr/local/redis-sentinel/etc/sentinel.conf
port 26379
dir /usr/local/redis-sentinel/data
sentinel monitor mymaster 172.16.10.55 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 60000
# sentinel client-reconfig-script mymaster /usr/local/redis-sentinel/bin/keepalived.sh # 这里我们在故障切换时,就不再执行脚本
sentinel monitor mymaster2 172.16.10.56 6380 1
sentinel down-after-milliseconds mymaster2 5000
sentinel parallel-syncs mymaster2 1
sentinel failover-timeout mymaster2 60000
3.下面启动相关Redis服务:
(1).启动 Redis服务;
(2).启动 Redis Sentinel 服务;
(3).测试 Redis master/slave 切换情况;

四、keepalived 部署:[ 部署在 10.53、10.54 ]
# keepalived 部署 参照 ”20150421:Redis Sentinel + keepalived 部署 “ 文章中的 keepalived 部署 一段
# 在此,就不再赘述

五、Twemproxy 部署:[ 部署在 10.53、10.54 ]
# Twemproxy 部署 参照 “Redis 中间件” 中的 “20150427:twemproxy 简介、安装配置”文章
# 在此,就不再赘述

六、Twemproxy Agent 部署:[ 部署在 10.53、10.54 ]
1.安装nodejs + npm:
yum -y install nodejs npm
2.安装forever:
npm install forever -g
3.安装Twemproxy Agent
(1).解压Twemproxy Agent 包,并复制到指定目录:
mv /tmp/redis-twemproxy-agent-master /usr/local/redis-twemproxy-agent
(2).修改redis-twemproxy-agent/lib/cli.js文件:
修改cli.parse里的文件路径为部署的路径,具体参照如下配置:
cli.parse
({
host: [‘h’, ‘Redis sentinel hostname’, ‘string’, ‘172.16.10.54’],
port: [‘p’, ‘Redis sentinel port number’, ‘number’, 26379],
config: [‘f’, ‘Path to twemproxy config’, ‘path’, ‘/usr/local/twemproxy/conf/nutcracker.yml’],
command: [‘c’, ‘Command to restart twemproxy’, ‘string’, ‘/etc/init.d/twemproxy restart’],
log: [‘l’, ‘The log file location’, ‘string’, ‘/usr/local/twemproxy/run/twemproxy_sentinel.log’]
});
(3).将 redis-twemproxy-agent/init.d/twemproxy_sentinel 复制到 /etc/init.d/ 目录下:
cp /usr/local/redis-twemproxy-agent/init.d/twemproxy_sentinel /etc/init.d/

# 修改该脚本redis-twemproxy-agent,nodejs,forever,的路径为实际路径,参考如下:
ROOT=/usr/local/redis-twemproxy-agent
EXEC=$ROOT/bin/redis_twemproxy_agent
NODE=/usr/bin/node
FOREVER=/usr/bin/forever
(4).启动 redis-twemproxy-agent 服务:
/etc/init.d/twemproxy_sentinel start

# 此测试结果,没有能证明 redis-twemproxy-agent 能自动修改 twemproxy 的配置文件,可能在文件配置方面有误,后续再研究

Redis Sentinel + keepalived 部署

一、Redis Sentinel简介:
Redis Sentinel 是一个分布式系统,你可以在一个架构中运行多个Sentinel 进程(progress),这些进程使用流言协议(gossipprotocols) 来接收关于主服务器是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器。
虽然Redis Sentinel只是一个单独的可执行文件 redis-sentinel,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 –sentinel 选项来启动 Redis Sentinel。
源码编译安装后,src目录有一个命名为redis-sentinel的程序。
对于redis-sentinel 程序,你可以用以下命令来启动Sentinel 系统:redis-sentinel /path/to/sentinel.conf

二、Redis Sentinel 的部署:
1.复制 redis 目录为 Redis Sentinel
# 这里我们基于原先 源码编译安装的redis目录,复制一个副本,改名为: Redis Sentinel
cp -r /usr/local/redis-3.0 /usr/local/redis-sentinel

2.正常安装:我们需要建 etc、bin、data、log 等目录;
但是,因为我们是复制redis目录,这写目录都有了,我们只需要稍作改动:
# 在 10.54、10.55 、 10.56 的redis上,都配置此文件,只是在 10.54[ 此机器上没有装redis ]上的配置文件 sentinel client-reconfig-script 注释掉
vim /usr/local/redis-sentinel/etc/sentinel.conf
port 26379
dir /usr/local/redis-sentinel/data
sentinel monitor mymaster 172.16.10.55 6379 1
sentinel down-after-milliseconds mymaster 5000 # 单位为毫秒
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 60000
sentinel client-reconfig-script mymaster /usr/local/redis-sentinel/bin/keepalived.sh # 检测故障后,调用的keepalive脚本,需要有X权限

3.部署redis-sentinel 启动脚本:
vim /usr/local/redis-sentinel/bin/startup.sh
#!/bin/bash
CMD_PATH=/usr/local/redis-sentinel/bin/redis-sentinel
CONF_PATH=/usr/local/redis-sentinel/conf/sentinel.conf
LOG_PATH=/usr/local/redis-sentinel/log/sentinel.log
${CMD_PATH} ${CONF_PATH} >> ${LOG_PATH} 2>&1 &

以下为参考脚本,暂不使用:
#!/bin/bash
#Configurations injected by install_server below….
EXEC=/usr/local/redis-sentinel/bin/redis-sentinel
CLIEXEC=/usr/local/redis-sentinel/bin/redis-cli
PIDFILE=/usr/local/redis-sentinel/log/redis-sentinel_26379.pid
CONF=”/usr/local/redis-sentinel/etc/sentinel.conf”
REDISPORT=”26379″
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
;;
status)
PID=$(cat $PIDFILE)
if [ ! -x /proc/${PID} ]
then
echo ‘Redis is not running’
else
echo “Redis is running ($PID)”
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo “Please use start, stop, restart or status as first argument”
;;
esac

三、keepalived 部署:
1.keepalive的安装,安装目录为/usr/local/keepalive
# 默认软件已上传并且解压,进入keepalived目录
./configure –prefix=/usr/local/keepalived
make && make install

# 在配置过程中可能出现某些软件包没有正确安装的提示,如openssl,popt等。
解决办法是使用 yum install openssl*以及yum install popt popt-deve l来安装缺少的软件包。
Keepalived 安装完成后,会在安装目录/usr/local/keepalived 生成 bin,etc,man,sbin 这4 个目录。其中etc为配置文件所在的目录。

2.配置 keepalived 环境变量
# 给root用户增加环境变量,在export PATH行之前加入一行:
vi ~/.bash_profile
PATH=$PATH:/usr/local/keepalived/sbin
保存退出,执行下面命令,使参数生效
. ~/.bash_profile

3.整理相关文件和命令,方便使用service 启动
cp -a /usr/local/keepalived/sbin/keepalived /usr/sbin/
cp -a /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp -a /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
# 让chkconfig管理新添加的服务
chkconfig –add keepalived
# 添加启动级别
chkconfig keepalived on
# 查看启动设置
chkconfig –list keepalived

4.keepalived配置文件的修改如下:配置文件目录在( /etc/keepalived/keepalived.conf )
# 172.16.10.55 master 的配置文件
global_defs {
notification_email
{
13501960667@139.com # 收件邮箱
}
notification_email_from mysql_lab@localhost # 发件邮箱
smtp_server localhost # 发件服务器
smtp_connect_timeout 30 # 超时时间
router_id HAOWU_55
}
vrrp_sync_group VG1 {
group
{
VI_1
}
}
vrrp_instance VI_1 {
state MASTER
# state BACKUP
# nopreempt
interface eth0
virtual_router_id 96
priority 110
advert_int 1
authentication
{
auth_type PASS
auth_pass Pa$$w0rd
}
virtual_ipaddress
{
172.16.10.251
}
}

# 172.16.10.56 slave 的配置文件
global_defs {
notification_email
{
13501960667@139.com
}
notification_email_from mysql_lab@localhost
smtp_server localhost
smtp_connect_timeout 30
router_id HAOWU_56
}
vrrp_sync_group VG1 {
group
{
VI_1
}
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 96
priority 100
advert_int 1
authentication
{
auth_type PASS
auth_pass Pa$$w0rd
}
virtual_ipaddress
{
172.16.10.251
}
}

注:
# 红色部分 是在我们实际配置中,需要修改的地方;
# 紫红色部分 是我们在HA操作中,可以参考的设置下:
具体理解如下:
主/从的state 都设置为: BACKUP ,同是将 priority( 110>100 ) 大的机器设置为 nopreempt 可以避免切换后,vip抢占问题;
nopreempt 只能工作于 state 为BACKUP 的状态下;

5.编写keepalived 切换脚本(55、56上配置此脚本):
vim /usr/local/redis-sentinel/bin/keepalived.sh
# 红色加粗脚本,只适用于主机宕机
#!/bin/bash
REDISCLI=”/usr/local/redis-3.0/bin/redis-cli”
if $REDISCLI info|grep role|grep -q master ;then
echo “start keepalived” >> ../log/sentinel.log
/etc/init.d/keepalived start >> ../log/sentinel.log
else
echo “stop keepalived” >> ../log/sentinel.log
/etc/init.d/keepalived stop >> ../log/sentinel.log
fi

# 下面脚本为改进脚本:
#!/bin/bash
EXEC=/usr/local/redis-3.0/bin/redis-server
CLIEXEC=/usr/local/redis-3.0/bin/redis-cli
CONF=”/usr/local/redis-3.0/etc/redis.conf”
REDISPORT=”6379″
KEEP_PID=`ps -A | grep keepalived |awk ‘{print $1}’ > /dev/null`

$CLIEXEC -p $REDISPORT info > /dev/null
if [ $? -eq 0 ]; then
if [ -z “$KEEP_PID” ]; then
# try to start keepalived again
/etc/init.d/keepalived start
else
echo “ERROR!!! server:keepalved is down!” | mail -s “ERROR!! keepalived is down !!!” 13501960667@139.com
fi
else
# try to start it again
# 以下部分 为了测试需要需要注释掉[ 下面这段脚本是判断能否重启redis,这里为测试需要,注释掉 ]
# $EXEC $CONF
# $CLIEXEC -p $REDISPORT info > /dev/null
# if [ $? -eq 0 ]; then
# exit 0
# else
# restart failed
/etc/init.d/keepalived stop
# fi
fi

# 给予脚本 执行权限:
chmod +x /usr/local/redis-sentinel/bin/keepalived.sh

四、部署测试:
1.测试keepalived 虚 ip 切换情况:
master(55) 和 slave(56) :
# 启动 keepalived
/etc/init.d/keepalived start
# 执行 ip addr:查看当前虚ip情况(停掉matser 的keepalived 看 虚IP 是否飘到 slave 上)

2.redis-sentinel启动测试:
/usr/local/redis-sentinel/bin/redis-sentinel /usr/local/redis-sentinel/etc/sentinel.conf
# 启动后,会有详细的信息输出,包括当前的主,redis-sentinel的个数,地址等

# 登陆 redis-sentinel 查看相关信息:
bin/redis-cli -h 172.16.10.56 -p 26379
172.16.10.56:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=172.16.10.55:6379,slaves=1,sentinels=3

3.redis 故障测试:
# 将 当前master(172.16.10.55) 关闭,看redis-sentinel 的切换日志
bin/redis-cli -h 172.16.10.55 -p 6379 shutdown
# 切换日志如下:
15296:X 22 Apr 16:38:49.292 # +sdown master mymaster 172.16.10.55 6379
15296:X 22 Apr 16:38:49.292 # +odown master mymaster 172.16.10.55 6379 #quorum 1/1
15296:X 22 Apr 16:38:49.292 # Next failover delay: I will not start a failover before Wed Apr 22 16:40:49 2015
15296:X 22 Apr 16:38:50.313 # +config-update-from sentinel 172.16.10.54:26379 172.16.10.54 26379 @ mymaster 172.16.10.55 6379
15296:X 22 Apr 16:38:50.313 # +switch-master mymaster 172.16.10.55 6379 172.16.10.56 6379
15296:X 22 Apr 16:38:50.313 * +slave slave 172.16.10.55:6379 172.16.10.55 6379 @ mymaster 172.16.10.56 6379
15296:X 22 Apr 16:38:50.441 # -script-error /usr/local/redis-sentinel/bin/keepalived.sh 0 2
15296:X 22 Apr 16:38:55.342 # +sdown slave 172.16.10.55:6379 172.16.10.55 6379 @ mymaster 172.16.10.56 6379

Redis 主从部署

Redis 部署说明:
redis使用两台机器,172.16.10.55,172.16.100.56。
55为redis master,56为redis slave,
监听默认的6379端口。

(1).创建Redis相关目录:
cd /usr/local/redis-3.0
# 如果相关目录已经在安装时,新建,下面步骤就忽略
mkdir -p /usr/local/redis-3.0/{data,log,etc}

(2).编辑Redis Master/Slave 相关配置文件:
vim etc/redis.conf

Master配置文件(生产实际配置文件不是这样,比较简单)
######################## GENERAL ######################
daemonize yes
pidfile /usr/local/redis-3.0/log/redis_6379.pid
port 6379
timeout 0
loglevel notice
logfile “/usr/local/redis-3.0/log/redis_6379.log”
syslog-enabled no
databases 16
#########################SAVE###########################
dbfilename dump.rdb
dir /usr/local/redis-3.0/data
stop-writes-on-bgsave-error no
#########################REPLICATION ###################
slave-serve-stale-data yes
slave-read-only yes
repl-timeout 60
repl-backlog-size 10mb
repl-backlog-ttl 3600
repl-ping-slave-period 10
min-slaves-to-write 0
min-slaves-max-lag 0
##########################SECURITY ######################
########################## LIMITS ########################
maxclients 2000
#########################APPEND ONLY MODE #############
appendonly no
appendfilename “appendonly.aof”
#########################SLOW LOG #######################
slowlog-log-slower-than 10000
slowlog-max-len 1000

**********************************************************************************

Slave配置文件(生产实际配置文件不是这样,比较简单)
######################## GENERAL ######################
daemonize yes
pidfile /usr/local/redis-3.0/log/redis_6379.pid
port 6379
timeout 0
loglevel notice
logfile “/usr/local/redis-3.0/log/redis.log”
syslog-enabled no
databases 16
#########################SAVE###########################
dbfilename dump.rdb
dir /usr/local/redis-3.0/data
stop-writes-on-bgsave-error no
#########################REPLICATION ###################
slaveof 172.16.10.55 6379
slave-serve-stale-data yes
slave-read-only yes
repl-timeout 60
repl-backlog-size 10mb
repl-backlog-ttl 3600
repl-ping-slave-period 10
min-slaves-to-write 0
min-slaves-max-lag 0
##########################SECURITY ######################
########################## LIMITS ########################
maxclients 2000
#########################APPEND ONLY MODE #############
appendonly no
appendfilename “appendonly.aof”
#########################SLOW LOG #######################
slowlog-log-slower-than 10000
slowlog-max-len 1000

(3).启动/关闭Redis服务:
启动Redis服务顺序:
先启动 Redis Master , 再启动 Redis Slave
关闭Redis服务顺序:
先关闭 Redis Master , 再关闭 Redis Slave

(4).验证Redis 主从复制是否正常:
最简单的方式,就是登录 Redis Master,设置一个值:select 0;set name Michael;
然后登录 Redis Slave ,看能不能获取到刚才设置的那个值:select 0;get name;

网上有种验证方式如下:
进入主从服务器的数据目录,查询对比所有服务器数据文件的散列值和文件大小:
find . -type f -name “*.rdb” | xargs md5sum
find . -type f -name “*.rdb” | xargs ls -l

生成报文摘要并验证,如果对比成功则数据已同步:
find . -type f -name “*.rdb” | xargs md5sum >biran
md5sum –check biran

Keepalived 简介、原理及服务部署

一、Keepalived的介绍:
keepalived是以 VRRP(Virtual Router Redundancy Protocol)协议为实现基础的,即虚拟路由冗余协议。
虚拟路由冗余协议可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面,有一个master和多个backup;
master上面有一个对外提供服务的vip,该路由器所在局域网内其他机器的默认路由为该vip;
master会发组播,当backup收不到vrrp包时,就认为master宕掉了;
这时,就需要根据VRRP的优先级,来选举一个backup当master。
这样的话就可以保证路由器的高可用了。

二、Keepalived的原理:
keepalived也是模块化设计,不同模块复杂不同的功能,下面是keepalived的组件:
core check vrrp libipfwc libipvs-2.4 libipvs-2.6

core:是keepalived的核心,复杂主进程的启动和维护,全局配置文件的加载解析等
check:负责healthchecker(健康检查),包括了各种健康检查方式,以及对应的配置的解析包括LVS的配置解析
vrrp:VRRPD子进程,VRRPD子进程就是来实现VRRP协议的
libipfwc:iptables(ipchains)库,配置LVS会用到
libipvs*:配置LVS会用到

# 注:
keepalived和LVS完全是两码事,只不过他们各负其责相互配合而已
Image
keepalived启动后会有三个进程
父进程:内存管理,子进程管理等等
子进程:VRRP子进程
子进程:healthchecker子进程

由图可知,两个子进程都被系统WatchDog看管,两个子进程各自复杂自己的事;
healthchecker子进程复杂检查各自服务器的健康程度,例如HTTP,LVS等等;
如果healthchecker子进程检查到MASTER上服务不可用了,就会通知本机上的兄弟VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态

三、Keepalived的部署:
1.安装相关依赖包:
yum -y install openssl* popt popt-devel

2.keepalive的安装,安装目录为/usr/local/keepalived
# 默认软件已上传 并且 解压,进入keepalived目录
./configure –prefix=/usr/local/keepalived
make && make install

# Keepalived 安装完成后,会在安装目录/usr/local/keepalived 生成 bin,etc,man,sbin 这4 个目录。其中etc为配置文件所在的目录。

3.配置 keepalived 环境变量
# 给root用户增加环境变量,在export PATH行之前加入一行:
vi ~/.bash_profile
PATH=$PATH:/usr/local/keepalived/sbin
保存退出,执行下面命令,使参数生效
. ~/.bash_profile

4.整理相关文件和命令,方便使用service 启动
cp -a /usr/local/keepalived/sbin/keepalived /usr/sbin/
cp -a /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp -a /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
# 让chkconfig管理新添加的服务
chkconfig –add keepalived
# 添加启动级别
chkconfig keepalived on
# 查看启动设置
chkconfig –list keepalived

5.keepalived配置文件的修改如下:配置文件目录在( /etc/keepalived/keepalived.conf ),没有就自己建一个
配置文件参考: linux — linux 配置文件详解 — keepalived 配置文件详解
vim /etc/keepalived/keepalived.conf
# master 参考配置文件
global_defs {
notification_email
{
13501960667@139.com # 收件邮箱
}
notification_email_from mysql_lab@localhost # 发件邮箱
smtp_server localhost # 发件服务器
smtp_connect_timeout 30 # 超时时间
router_id HAOWU_55
}
vrrp_sync_group VG1 {
group
{
VI_1
}
}
vrrp_instance VI_1 {
state MASTER
# state BACKUP
# nopreempt
interface eth0
virtual_router_id 96
priority 110
advert_int 1
authentication
{
auth_type PASS
auth_pass Pa$$w0rd
}
virtual_ipaddress
{
172.16.10.251
}
}

注:
# 红色部分 是在我们实际配置中,需要修改的地方;
# 紫红色部分 是我们在HA操作中,可以参考的设置下:
具体理解如下:
主/从的state 都设置为: BACKUP ,同是将 priority( 110>100 ) 大的机器设置为 nopreempt 可以避免切换后,vip抢占问题;
nopreempt 只能工作于 state 为BACKUP 的状态下;

# 如果利用keepalived调用脚本,则脚本里不能含有weight ,否则,会无法调用脚本。

Redis 3.0 编译安装

官方主站:http://www.redis.io/
下载地址:http://www.redis.cn/download.html
Command API: http://www.redis.cn/commands.html
Redis官方文档:http://redis.io/documentation

一.Redis 介绍:
Redis是Remote Dictionary Server的缩写。他本质上一个Key/Value数据库,与Memcached类似的NoSQL型数据库,但是他的数据可以持久化的保存在磁盘上,解决了服务重启后数据不丢失的问题,他的值可以是string(字符串)、list(列表)、sets(集合)或者是ordered sets(被排序的集合),所有的数据类型都具有push/pop、add/remove、执行服务端的并集、交集、两个sets集中的差别等等操作,这些操作都是具有原子性的,Redis还支持各种不同的排序能力。

二.Redis 部署
1.安装相关依赖包:
yum -y install gcc gcc-c++ cmake make

2.安装tcmalloc包[ 尝试采用新的内存分配方式 ]
Redis并没有自己实现内存池,没有在标准的系统内存分配器上再加上自己的东西。
所以系统内存分配器的性能及碎片率会对Redis造成一些性能上的影响。
在最新版本中,jemalloc已经作为源码包的一部分包含在源码包中,所以可以直接被使用。
如果要使用tcmalloc的话,是需要自己安装的。

tcmalloc是google-proftools( http://code.google.com/p/gperftools/downloads/list)中的一部分,
所以我们实际上需要安装google-proftools。如果你是在64位机器上进行安装,需要先安装其依赖的libunwind库,32位的系统不需要
下载地址: http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz

(1).安装libunwind
tar zxvf libunwind-0.99-alpha.tar.gz
cd libunwind-0.99-alpha/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install

(2).安装gperftools
tar zxvf gperftools-2.1.tar.gz
cd gperftools-2.1
./configure –disable-cpu-profiler –disable-heap-profiler –disable-heap-checker –disable-debugalloc –enable-minimal
make && make install
cd /usr/local/lib
ln -sv libtcmalloc_minimal.so.4.1.2 libtcmalloc.so
# 加粗部分如果不做的话,后面编译redis会报错: usr/bin/ld: cannot find ltcmalloc
echo “/usr/local/lib” > /etc/ld.so.conf.d/usr_local_lib.conf #如果没有这个文件,自己建一个
/sbin/ldconfig

3.Redis 安装:
tar zxvf redis-3.0.0.tar.gz
cd redis-3.0.0
mkdir -p /usr/local/redis-3.0
# make prefix= install
# 将redis安装在/bin下/usr/local/redis-3.0/bin下
# make PREFIX=/usr/local/redis-3.0 install # 此方式安装,使用linux默认的内存分配方式
make PREFIX=/usr/local/redis-3.0 USE_TCMALLOC=yes FORCE_LIBC_MALLOC=yes install

4.建相关目录,并配置redis.conf 文件[简单配置]
cd /usr/local/redis-3.0/
mkdir etc #存放配置文件,这里目录名,可建为:conf
mkdir log #存放日志和pid文件
mkdir data #存放数据
vim etc/redis.conf
daemonize yes
port 6379
pidfile /usr/local/redis-3.0/log/redis_6379.pid
dir /usr/local/redis-3.0/data
logfile /usr/local/redis-3.0/log/redis_6379.log

5.Redis服务启动、关闭
(1).启动服务:
/usr/local/redis-3.0/bin/redis-server /usr/local/redis-3.0/etc/redis.conf
注:
此命令仅有一个启动参数,指定目录下的配置文件,不加参数执行默认配置。
测试启动:
/usr/local/redis-3.0/bin/redis-cli ping
返回PONG,则启动成功。
查看端口是否被占用:
netstat -ntlp |grep 6379

(2).关闭服务:
/usr/local/redis-3.0/bin/redis-cli shutdown
如果非默认端口,可指定端口:
/usr/local/redis-3.0/bin/redis-cli -p 6380 shutdown

(3).验证redis内存分配方式是否在使用tcmalloc
lsof -n |grep tcmalloc
redis-ser 2754 root mem REG 253,0 1078467 1725996 /usr/local/lib/libtcmalloc_minimal.so.4.1.2

6.Redis 服务启动脚本
redis 本身提供了redis安装脚本:utils/install_server.sh
但 这个脚本包括安装服务,有点烦,我们直接取其安装脚本:
#!/bin/sh
#Configurations injected by install_server below….
EXEC=/usr/local/redis-3.0/bin/redis-server
CLIEXEC=/usr/local/redis-3.0/bin/redis-cli
PIDFILE=/usr/local/redis-3.0/log/redis_6379.pid
CONF=”/usr/local/redis-3.0/etc/redis.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
;;
status)
PID=$(cat $PIDFILE)
if [ ! -x /proc/${PID} ]
then
echo ‘Redis is not running’
else
echo “Redis is running ($PID)”
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo “Please use start, stop, restart or status as first argument”
;;
esac

Redis的复制流程

Redis的复制功能是基于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了Redis的复制功能,就一定会有内存快照发生,那么首先要注意你的系统内存容量规划

Redis复制流程在Slave和Master端各自是一套状态机流转,涉及的状态信息如下:
Slave 端:
REDIS_REPL_NONE
REDIS_REPL_CONNECT
REDIS_REPL_CONNECTED
Master端:

          REDIS_REPL_WAIT_BGSAVE_START
REDIS_REPL_WAIT_BGSAVE_END
REDIS_REPL_SEND_BULK
REDIS_REPL_ONLINE

整个状态机流程过程如下:
(1).Slave端在配置文件中添加了slave of指令,于是Slave启动时读取配置文件,初始状态为REDIS_REPL_CONNECT。
(2).Slave端在定时任务serverCron(Redis内部的定时器触发事件)中连接Master,发送sync命令,然后阻塞等待master发送回其内存快照文件(最新版的Redis已经不需要让Slave阻塞)。
     (3).Master端收到sync命令简单判断是否有正在进行的内存快照子进程,没有则立即开始内存快照,有则等待其结束,当快照完成后会将该文件发送给Slave端。
     (4).Slave端接收Master发来的内存快照文件,保存到本地,待接收完成后,清空内存表,重新读取Master发来的内存快照文件,重建整个内存表数据结构,并最终状态置位为 REDIS_REPL_CONNECTED状态,Slave状态机流转完成。
     (5).Master端在发送快照文件过程中,接收的任何会改变数据集的命令都会暂时先保存在Slave网络连接的发送缓存队列里(list数据结构),待快照完成后,依次发给Slave,之后收到的命令相同处理,并将状态置位为 REDIS_REPL_ONLINE。
整个复制过程完成,流程如下图所示:
 image1
Redis复制机制的缺陷

      从上面的流程可以看出,Slave从库在连接Master主库时,Master会进行内存快照,然后把整个快照文件发给Slave,
     也就是没有象MySQL那样有复制位置的概念,即无增量复制,这会给整个集群搭建带来非常多的问题。

比如一台线上正在运行的Master主库配置了一台从库进行简单读写分离,这时Slave由于网络或者其它原因与Master断开了连接,

     那么当Slave进行重新连接时,需要重新获取整个Master的内存快照,Slave所有数据跟着全部清除,
     然后重新建立整个内存表,一方面Slave恢复的时间会非常慢,另一方面也会给主库带来压力。
所以基于上述原因,如果你的Redis集群需要主从复制,那么最好事先配置好所有的从库,避免中途再去增加从库。

Cache还是Storage
在我们分析过了Redis的复制与持久化功能后,我们不难得出一个结论,实际上Redis目前发布的版本还都是一个单机版的思路,主要的问题集中在,持久化方式不够成熟,复制机制存在比较大的缺陷,这时我们又开始重新思考Redis的定位:Cache还是Storage?
如果作为Cache的话,似乎除了有些非常特殊的业务场景,必须要使用Redis的某种数据结构之外,我们使用Memcached可能更合适,毕竟Memcached无论客户端包和服务器本身更久经考验。
如果是作为存储Storage的话,我们面临的最大的问题是无论是持久化还是复制都没有办法解决Redis单点问题,即一台Redis挂掉了,没有太好的办法能够快速的恢复,通常几十G的持久化数据,Redis重启加载需要几个小时的时间,而复制又有缺陷,如何解决呢?

Redis可扩展集群搭建
1. 主动复制避开Redis复制缺陷。
既然Redis的复制功能有缺陷,那么我们不妨放弃Redis本身提供的复制功能,我们可以采用主动复制的方式来搭建我们的集群环境。
所谓主动复制是指由业务端或者通过代理中间件对Redis存储的数据进行双写或多写,通过数据的多份存储来达到与复制相同的目的,
               主动复制不仅限于用在Redis集群上,目前很多公司采用主动复制的技术来解决MySQL主从之间复制的延迟问题,
               比如Twitter还专门开发了用于复制和分区的中间件gizzard(https://github.com/twitter/gizzard) 。

主动复制虽然解决了被动复制的延迟问题,但也带来了新的问题,就是数据的一致性问题,数据写2次或多次,如何保证多份数据的一致性呢?

               如果你的应用对数据一致性要求不高,允许最终一致性的话,那么通常简单的解决方案是可以通过时间戳或者vector clock等方式,
               让客户端同时取到多份数据并进行校验,如果你的应用对数据一致性要求非常高,那么就需要引入一些复杂的一致性算法比如Paxos来保证数据的一致性,
               但是写入性能也会相应下降很多。

通过主动复制,数据多份存储我们也就不再担心Redis单点故障的问题了,如果一组Redis集群挂掉,我们可以让业务快速切换到另一组Redis上,降低业务风险。

2. 通过presharding进行Redis在线扩容。
通过主动复制我们解决了Redis单点故障问题,那么还有一个重要的问题需要解决:容量规划与在线扩容问题。
我们前面分析过Redis的适用场景是全部数据存储在内存中,而内存容量有限,那么首先需要根据业务数据量进行初步的容量规划,

                比如你的业务数据需要100G存储空间,假设服务器内存是48G,我们大约需要3~4台服务器来存储。
                这个实际是对现有业务情况所做的一个容量规划,假如业务增长很快,很快就会发现当前的容量已经不够了,Redis里面存储的数据很快就会超过物理内存大小,
                那么如何进行Redis的在线扩容呢?

Redis的作者提出了一种叫做presharding的方案来解决动态扩容和数据分区的问题,

     实际就是在同一台机器上部署多个Redis实例的方式,当容量不够时将多个实例拆分到不同的机器上,这样实际就达到了扩容的效果。

拆分过程如下:
在新机器上启动好对应端口的Redis实例。
配置新端口为待迁移端口的从库。
待复制完成,与主库完成同步后,切换所有客户端配置到新的从库的端口。
配置从库为新的主库。
移除老的端口实例。
重复上述过程迁移好所有的端口到指定服务器上。
     以上拆分流程是Redis作者提出的一个平滑迁移的过程,不过该拆分方法还是很依赖Redis本身的复制功能的,
     如果主库快照数据文件过大,这个复制的过程也会很久,同时会给主库带来压力。所以做这个拆分的过程最好选择为业务访问低峰时段进行。

Redis复制的改进思路
我们线上的系统使用了我们自己改进版的Redis,主要解决了Redis没有增量复制的缺陷,能够完成类似Mysql Binlog那样可以通过从库请求日志位置进行增量复制。
我们的持久化方案是首先写Redis的AOF文件,并对这个AOF文件按文件大小进行自动分割滚动,同时关闭Redis的Rewrite命令,
     然后会在业务低峰时间进行内存快照存储,并把当前的AOF文件位置一起写入到快照文件中,这样我们可以使快照文件与AOF文件的位置保持一致性,
     这样我们得到了系统某一时刻的内存快照,并且同时也能知道这一时刻对应的AOF文件的位置,那么当从库发送同步命令时,
     我们首先会把快照文件发送给从库,然后从库会取出该快照文件中存储的AOF文件位置,并将该位置发给主库,主库会随后发送该位置之后的所有命令,
     以后的复制就都是这个位置之后的增量信息了。
 image2
Redis与MySQL的结合
目前大部分互联网公司使用MySQL作为数据的主要持久化存储,那么如何让Redis与MySQL很好的结合在一起呢?
     我们主要使用了一种基于MySQL作为主库,Redis作为高速数据查询从库的异构读写分离的方案。

为此我们专门开发了自己的MySQL复制工具,可以方便的实时同步MySQL中的数据到Redis上。

 image3
(MySQL-Redis 异构读写分离)

总结:

Redis的复制功能没有增量复制,每次重连都会把主库整个内存快照发给从库,所以需要避免向在线服务的压力较大的主库上增加从库。
Redis的复制由于会使用快照持久化方式,所以如果你的Redis持久化方式选择的是日志追加方式(aof),

     那么系统有可能在同一时刻既做aof日志文件的同步刷写磁盘,又做快照写磁盘操作,这个时候Redis的响应能力会受到影响。
     所以如果选用aof持久化,则加从库需要更加谨慎。
可以使用主动复制和presharding方法进行Redis集群搭建与在线扩容。

Redis 3.0 新特性,支持redis 集群

Redis是一个开源、基于C语言、基于内存亦可持久化的高性能NoSQL数据库,同时,它还提供了多种语言的API。

近日,Redis 3.0在经过6个RC版本后,其正式版终于发布了。

Redis 3.0的最重要特征是对Redis集群的支持,此外,该版本相对于2.8版本在性能、稳定性等方面都有了重大提高。

一、Redis 3.0正式版相对于RC6版本的改进内容包括:

1.修复了无磁盘情况下的的复制问题;

2.在角色变化后对BLPOP复制进行了测试;

3.改进了prepareClientToWrite()错误处理;

4.移除了dict.c中不再使用的函数。

 

二、Redis 3.0版本相对于2.8版本带来的主要新特性包括:

1.实现了分布式的Redis即Redis Cluster,从而做到了对集群的支持;

2.引入了全新的”embedded string” 对象编码方式,从而实现了更少的缓存丢失和在特定的工作负载下速度的大幅提升;

3.AOF重写过程中的 “last write” 操作降低了AOF child -> parent数据传输的延迟

4.大幅提升LRU算法的性能以用于值的失效;

5.WAIT命令能够阻塞传输到指定数量从节点的写操作;

6.实现了对MIGRATE连接缓存的支持,从而大幅提升键值迁移的性能;

7.为MIGARTE新增了参数:COPY和REPLACE;

8.CLIENT PAUSE命令实现了在指定时间内停止处理客户端请求;

9.提高了BITCOUNT、INCR操作的性能;

10.CONFIG SET能够接受不同单位的内存值,如CONFIG SET maxmemory 1gb;

11.调整Redis日志格式。

 

文章转载自:开源中国

MySQL的权限有哪些及如何设置

  • 一.权限表
     mysql数据库中的3个权限表:user 、db、 host

MYSQL验证权限的过程是:
     1)先从user表中的host、 user、 password这3个字段中判断连接的IP、用户名、密码是否存在表中,存在则通过身份验证;
     2)通过权限验证,进行权限分配时,按照user、db、tables_priv、columns_priv的顺序进行分配。
          即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检查db, tables_priv,columns_priv;
          如果为N,则到db表中检查此用户对应的具体数据库,并得到db中为Y的权限;
          如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,
          以此类推。
 

二.MySQL各种权限(共27个) (以下操作都是以root身份登陆进行grant授权)

1. usage      连接(登陆)权限,建立一个用户,就会自动授予其usage权限(默认授予)。      

mysql> grant usage on *.* to ‘p1′@’localhost’ identified by ‘123′;

     该权限只能用于数据库登陆,不能执行任何操作;且usage权限不能被回收,也即REVOKE用户并不能删除用户。
 

2. select      必须有select的权限,才可以使用select table      

mysql> grant select on pyt.* to ‘p1′@’localhost’;

      mysql> select * from shop;
 

3. create      必须有create的权限,才可以使用create table

     mysql> grant create on pyt.* to ‘p1′@’localhost’;
 

4. create routine      必须具有create routine的权限,才可以使用{create |alter|drop} {procedure|function}      

mysql> grant create routine on pyt.* to ‘p1′@’localhost’;      

当授予create routine时,自动授予EXECUTE, ALTER ROUTINE权限给它的创建者:      

mysql> show grants for ‘p1′@’localhost’;  

5. create temporary tables(注意这里是tables,不是table)      

必须有create temporary tables的权限,才可以使用create temporary tables.      

mysql> grant create temporary tables on pyt.* to ‘p1′@’localhost’;      

mysql@mydev ~]$ mysql -h localhost -u p1 -p pyt

mysql> create temporary table tt1(id int);

 

6. create view      必须有create view的权限,才可以使用create view      

mysql> grant create view on pyt.* to ‘p1′@’localhost’;

       mysql> create view v_shop as select price from shop;
 

7. create user      要使用CREATE USER,必须拥有mysql数据库的全局CREATE USER权限,或拥有INSERT权限。  

mysql> grant create user on *.* to ‘p1′@’localhost’;

     或:mysql> grant insert on *.* to p1@localhost;
 

8. insert      必须有insert的权限,才可以使用insert into ….. values….

9. alter

     必须有alter的权限,才可以使用alter table

     alter table shop modify dealer char(15);
 

10. alter routine      必须具有alter routine的权限,才可以使用{alter |drop} {procedure|function}      

mysql>grant alter routine on pyt.* to ‘p1′@’ localhost ‘;      

mysql> drop procedure pro_shop;

mysql> revoke alter routine on pyt.* from ‘p1′@’localhost’;  

11. update      必须有update的权限,才可以使用update table      

mysql> update shop set price=3.5 where article=0001 and dealer=’A’; 

12. delete

     必须有delete的权限,才可以使用delete from ….where….(删除表中的记录)

13. drop

     必须有drop的权限,才可以使用drop database db_name; drop table tab_name;    

drop view vi_name; drop index in_name;

14. show database

通过show database只能看到你拥有的某些权限的数据库,除非你拥有全局SHOW DATABASES权限。      

对于p1@localhost用户来说,没有对mysql数据库的权限,所以以此身份登陆查询时,无法看到mysql数据库:  

15. show view      必须拥有show view权限,才能执行show create view。      

mysql> grant show view on pyt.* to p1@localhost;    

mysql> show create view v_shop;

16. index

     必须拥有index权限,才能执行[create |drop] index      

mysql> grant index on pyt.* to p1@localhost;      

mysql> create index ix_shop on shop(article);    

mysql> drop index ix_shop on shop;

17. execute

     执行存在的Functions,Procedures

18. lock tables      必须拥有lock tables权限,才可以使用lock tables  

mysql> grant lock tables on pyt.* to p1@localhost;   19. references

     有了REFERENCES权限,用户就可以将其它表的一个字段作为某一个表的外键约束。
 

20. reload      必须拥有reload权限,才可以执行flush [tables | logs | privileges]

mysql> grant reload on *.* to ‘p1′@’localhost’;  

21. replication client      拥有此权限可以查询master server、slave server状态。      

mysql> show master status;      

ERROR 1227 (42000): Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation

mysql> grant Replication client on *.* to p1@localhost;  

或:mysql> grant super on *.* to p1@localhost;  

22. replication slave      拥有此权限可以查看从服务器,从主服务器读取二进制日志。      

mysql> show slave hosts;      

ERROR 1227 (42000): Access denied; you need the REPLICATION SLAVE privilege for this operation      

mysql> show binlog events;      

ERROR 1227 (42000): Access denied; you need the REPLICATION SLAVE privilege for this operation      

mysql> grant replication slave on *.* to p1@localhost;      

mysql> show slave hosts;  

23. Shutdown      关闭MySQL:  

24. grant option      拥有grant option,就可以将自己拥有的权限授予其他用户(仅限于自己已经拥有的权限)      

mysql> grant Grant option on pyt.* to p1@localhost;  

25. file      拥有file权限才可以执行 select ..into outfile和load data infile…操作,但是不要把file, process, super权限授予管理员以外的账号,这样存在严重的安全隐患。      

mysql> grant file on *.* to p1@localhost;      

mysql> load data infile ‘/home/mysql/pet.txt’ into table pet;

26. super

     这个权限允许用户终止任何查询;修改全局变量的SET语句;使用CHANGE MASTER,PURGE MASTER LOGS。      mysql> grant super on *.* to p1@localhost;      mysql> purge master logs before ‘mysql-bin.000006′;

27. process

     通过这个权限,用户可以执行SHOW PROCESSLIST和KILL命令。

默认情况下,每个用户都可以执行SHOW PROCESSLIST命令,但是只能查询本用户的进程。      

mysql> show processlist;  

注:      管理权限(如 super, process, file等)不能够指定某个数据库,on后面必须跟*.*

linux系统下如何查看分区uuid

1. sudo blkid
/dev/sda1: UUID=”9ADAAB4DDAAB250B” TYPE=”ntfs”
/dev/sdb1: UUID=”B2FCDCFBFCDCBAB5″ TYPE=”ntfs”
/dev/sdb5: UUID=”46FC5C74FC5C5FEB” TYPE=”ntfs”
/dev/sdb6: TYPE=”swap” UUID=”2cec6109-5bcf-45a3-ba1b-978b041c037f”
/dev/sdb8: UUID=”9ee6f22d-b394-422c-9b4a-1525a3220942″ SEC_TYPE=”ext2″ TYPE=”ext3″
/dev/sdb7: UUID=”4bcb9381-6e25-4304-8743-f882039ff3ad” TYPE=”ext3″
2. ls -l /dev/disk/by-uuid

mysql 审计插件的安装和使用


很多人都一直在寻找mysql的审计插件,目前,mariadb 官方已经提供了审计功能,并且含有审计插件,可以在mysql使用
具体方式:
       就是先下载安装一个mriadb ,安装完成后,按如下方式操作:
1. 在mariadb 里执行:SHOW VARIABLES LIKE ‘plugin_dir’;
    查找插件目录,进入插件目录,将名称为:server_audit.so 复制到 mysql  的插件目录(mysql插件目录查询方式,同mariadb)
2.mysql 和 mariadb 中,审计插件的安装方式:
(1).mysql 的安装方式
     INSTALL PLUGIN server_audit SONAME ‘server_audit.so’;
 
(2).mariadb的安装方式:
     INSTALL PLUGIN server_audit SONAME ‘server_audit’;
(3).卸载插件:
     uninstall plugin server_sudit
 
3.审计插件相关状态参数的查看命令
状态参数查看:
mysql> SHOW global VARIABLES LIKE ‘%audit%’;
mysql> SHOW global status LIKE ‘%audit%’;
 
4.启用审计插件:
mysql> set global server_audit_logging=1;
5.设置记录的内容:
mysql> set global  server_audit_events =’connect,query,TABLE’;
注:
       永久生效的话,写入到my.cnf文件里:
[mysqld]
server_audit_events=connect,query,table
6.其它相关说明
mysql>  SET GLOBAL server_audit_excl_users=’confluence,hoss_user,jira,nagios,sonar,test,tm_jdbc,tmp_test,mpm,repl,cacti,dba_test’;
mysql>  set global server_audit_incl_users=’haowu_dev,haowu_test,root,dev_debug’;
 

参数说明:
server_audit_output_type:指定日志输出类型,可为SYSLOG或FILE
server_audit_logging:启动或关闭审计
server_audit_events:指定记录事件的类型,可以用逗号分隔的多个值(connect,query,table),如果开启了查询缓存(query cache),查询直接从查询缓存返回数据,将没有table记录
server_audit_file_path:如server_audit_output_type为FILE,使用该变量设置存储日志的文件,可以指定目录,默认存放在数据目录的server_audit.log文件中
server_audit_file_rotate_size:限制日志文件的大小
server_audit_file_rotations:指定日志文件的数量,如果为0日志将从不轮转
server_audit_file_rotate_now:强制日志文件轮转
server_audit_incl_users:指定哪些用户的活动将记录,connect将不受此变量影响,该变量比server_audit_excl_users优先级高
server_audit_syslog_facility:默认为LOG_USER,指定facility
server_audit_syslog_ident:设置ident,作为每个syslog记录的一部分
server_audit_syslog_info:指定的info字符串将添加到syslog记录
server_audit_syslog_priority:定义记录日志的syslogd priority
server_audit_excl_users:该列表的用户行为将不记录,connect将不受该设置影响
server_audit_mode:标识版本,用于开发测试
7.日志样式:
Image