龚哥哥 - 山里男儿 爱生活、做自己!
redis事务
发表于 2017-6-26 | 浏览(21400) | 服务器

一、事务

1、开启事务 multi

2、提交事务 exec

3、取消事务 discard

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name devil
QUEUED
127.0.0.1:6379> set age 26
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
127.0.0.1:6379> get sex
"2"
127.0.0.1:6379> get age
"26"
127.0.0.1:6379>
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a 100
QUEUED
127.0.0.1:6379> del age
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get age
"26"
127.0.0.1:6379> get a
(nil)
127.0.0.1:6379>

二、乐观锁

client-1 开启watch,并在事务中修改name

127.0.0.1:6379> get name
"mogui"
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name devil
QUEUED
127.0.0.1:6379> exec
(nil)

client-2 修改name

127.0.0.1:6379> get name
"mogui"
127.0.0.1:6379> get name
"mogui"
127.0.0.1:6379> set name gong
OK
127.0.0.1:6379> get name
"gong"

client-1 执行exec

127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get name
"gong"

三、发布及订阅消息

client-1 订阅devil频道

127.0.0.1:6379> subscribe devil
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "devil"
3) (integer) 1

client-2 发布频道devil消息

127.0.0.1:6379> publish devil hello
(integer) 1

client-1 订阅频道接收到的消息

1) "message"
2) "devil"
3) "hello"

阅读全文

HAProxy编译安装及配置详解
发表于 2017-6-17 | 浏览(19721) | 服务器

简介

HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。

HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。

HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。

HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

结合Keepalived搭建高可用负载均衡服务器架构,详情可参考本博客中的另一篇文章。

HAProxy官网:http://www.haproxy.org/

架构图

Image

准备工作

mkdir /data
cd /data
mkdir soft src www
mkdir soft/haproxy

下载安装

wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.5.tar.gz
tar -zxvf haproxy-1.7.5.tar.gz
cd haproxy-1.7.5
make TARGET=linux2628 ARCH=x86_64 PREFIX=/data/soft/haproxy
make install PREFIX=/data/soft/haproxy

参数说明

使用 [ uname -r ] 查看内核
    如:2.6.18-371.el5,此时该参数就为linux26;内核 大于2.6.28的用:TARGET=linux2628

内核版本
    TARGET=linux26

系统位数
    ARCH=x86_64

haprpxy安装路径
    PREFIX=/data/soft/haproxy

添加haproxy用户和组

groupadd haproxy
useradd -g haproxy haproxy

制作haproxy操作脚本 [ vim /etc/init.d/haproxy ]

#!/bin/sh
#chkconfig: 2345 80 90
#description:haproxy run

# haproxy操作脚本
# @author   Devil
# @version  0.0.1

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/data/soft/haproxy/sbin
PROGDIR=/data/soft/haproxy
PROGNAME=haproxy
DAEMON=$PROGDIR/sbin/$PROGNAME
CONFIG=$PROGDIR/$PROGNAME.cfg
PIDFILE=$PROGDIR/$PROGNAME.pid
DESC="HAProxy daemon"
SCRIPTNAME=/etc/init.d/$PROGNAME
set -e
# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

start()
{
    echo -n "Starting $DESC: $PROGNAME"
    $DAEMON -f $CONFIG
    echo "."
}

stop()
{
    echo -n "Stopping $DESC: $PROGNAME"
    kill $(cat $PIDFILE)
    echo "."
}

restart()
{
    echo -n "Restarting $DESC: $PROGNAME"
    $DAEMON -f $CONFIG -p $PIDFILE -st $(cat $PIDFILE)
    echo "."
}

case "$1" in
    start)
        start
    ;;
    stop)
        stop
    ;;
    restart)
        restart
    ;;
    *)
        echo "Usage: systemctl {start|stop|restart} $PROGNAME" >&2
        exit 1
    ;;
esac
exit 0

赐予可执行权限

chmod x+ /etx/init.d/haproxy

添加haproxy命令软连接

ln /etc/init.d/haproxy /usr/bin/haproxy

注册服务

chkconfig --add haproxy

设置开启启动

chkconfig haproxy on

haproxy操作命令

systemctl start haproxy     启动
systemctl restart haproxy   重启
systemctl stop haproxy      停止

配置文件 [ vim /data/soft/haproxy/haproxy.cfg ] 配置文件不存在则创建

#---------------------------------------------------------------------
# 全局配置
#---------------------------------------------------------------------
global
    log 127.0.0.1 local0 #[日志输出配置,所有日志都记录在本机,通过local0输出]
    #log 127.0.0.1 local1 notice #定义haproxy 日志级别[error warringinfo debug]
    daemon #以后台形式运行harpoxy
    nbproc 1 #设置进程数量
    maxconn 4000 #默认最大连接数,需考虑ulimit-n限制, 默认4000
    user haproxy #运行haproxy的用户
    group haproxy #运行haproxy的用户所在的组
    pidfile /data/soft/haproxy/haproxy.pid #haproxy 进程PID文件
    chroot /data/soft/haproxy #chroot运行路径
    #ulimit-n 819200 #ulimit 的数量限制
    #debug #haproxy 调试级别,建议只在开启单进程的时候调试
    #quiet

#---------------------------------------------------------------------
# 默认配置
#---------------------------------------------------------------------
defaults
    mode http #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
    log global #采用全局定义的日志
    option httplog #日志类别,采用httplog
    option dontlognull #不记录健康检查日志信息
    retries 3 #3次连接失败就认为是服务器不可用,也可以通过后面设置
    option forwardfor #如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip
    option httpclose #每次请求完毕后主动关闭http通道,haproxy不支持keep-alive,只能模拟这种模式的实现
    #option redispatch #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器,以后将不支持
    option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
    maxconn 6000 #默认的最大连接数
    timeout connect 5000ms #连接超时
    timeout client 30000ms #客户端超时
    timeout server 30000ms #服务器超时
    #timeout check 2000 #心跳检测超时
    #timeout http-keep-alive 10s #默认持久连接超时时间
    #timeout http-request 10s #默认http请求超时时间
    #timeout queue 1m #默认队列超时时间
    balance roundrobin #设置默认负载均衡方式,轮询方式,类似于nginx的ip_hash

#---------------------------------------------------------------------
# 统计页面配置
#---------------------------------------------------------------------
listen stats
    bind 0.0.0.0:1080 #设置Frontend和Backend的组合体,监控组的名称,按需要自定义名称
    stats refresh 30s #统计页面自动刷新时间
    stats uri /stats #统计页面url
    stats realm Gong Cloud Haproxy #统计页面密码框上提示文本
    stats auth admin:admin #设置监控页面的用户和密码,格式 用户名:密码,可以设置多个用户名
    stats auth devil:devil #第二个用户和密码
    stats hide-version #隐藏统计页面上HAProxy的版本信息
    stats admin if TRUE #设置手工启动/禁用,后端服务器(haproxy-1.4.9以后版本)

#---------------------------------------------------------------------
# 设置haproxy错误页面
#---------------------------------------------------------------------
#errorfile 403 /data/soft/haproxy/www/errorfiles/403.http
#errorfile 500 /data/soft/haproxy/www/errorfiles/500.http
#errorfile 502 /data/soft/haproxy/www/errorfiles/502.http
#errorfile 503 /data/soft/haproxy/www/errorfiles/503.http
#errorfile 504 /data/soft/haproxy/www/errorfiles/504.http

#---------------------------------------------------------------------
# 请求入口处理
#---------------------------------------------------------------------
frontend main
    # 这里建议使用bind *:80的方式,要不然做集群高可用的时候有问题,vip切换到其他机器就不能访问了。
    bind *:80

    # 定义静态规则
    acl url_static path_beg -i /static /images /javascript /stylesheets
    acl url_static path_end -i .jpg .gif .png .css .js .html
    acl host_static hdr_beg(host) -i img. imgs. video. videos. ftp. image. download.

    # 定义动态规则
    acl url_php path_end -i .php

    # 请求归纳
    use_backend static if url_static or host_static
    use_backend dynamic if url_php

    # 不满足则响应backend的默认页面
    default_backend dynamic

#---------------------------------------------------------------------
# 静态请求处理
#---------------------------------------------------------------------
backend static
    # 请求类型
    mode http

    # 分配算法 balance roundrobin 负载轮询,balance source 保存session值,支持static-rr,leastconn,first,uri等参数
    balance roundrobin

    # 实际处理请求的服务器列表
    # cookie 1表示serverid为1
    # weight 代表权重
    # check inter 1500 是检测心跳频率 
    # rise 2是2次正确认为服务器可用
    # fall 3是3次失败认为服务器不可用
    server static01 192.168.0.100:80 cookie 1 weight 1 check inter 2000 rise 2 fall 3

#---------------------------------------------------------------------
# 动态请求处理
#---------------------------------------------------------------------
backend dynamic
    # 请求类型
    mode http

    # 分配算法 balance roundrobin 负载轮询,balance source 保存session值,支持static-rr,leastconn,first,uri等参数
    balance roundrobin

    # 实际处理请求的服务器列表
    # cookie 1表示serverid为1
    # weight 代表权重
    # check inter 1500 是检测心跳频率 
    # rise 2是2次正确认为服务器可用
    # fall 3是3次失败认为服务器不可用
    server web01 192.168.0.103:80 cookie 1 weight 1 check inter 2000 rise 2 fall 3

配置日志记录

1、创建haproxy日志目录
    mkdir /var/log/haproxy

2、vim /etc/rsyslog.conf 在底部添加
    # haproxy log
    $ModLoad imudp
    $UDPServerRun 514
    local0.* /var/log/haproxy/haproxy.log

3、重启日志服务
    systemctl restart rsyslog

访问haproxy查看状态 [ http://host:1080/stats ]

Image

8种负载均衡算法

1、roundrobin
    表示简单的轮询,每个服务器根据权重轮流使用,在服务器的处理时间平均分配的情况下这是最流畅和公平的算法。该算法是动态的,对于实例启动慢的服务器权重会在运行中调整。

2、leastconn
    连接数最少的服务器优先接收连接。leastconn建议用于长会话服务,例如LDAP、SQL、TSE等,而不适合短会话协议。如HTTP.该算法是动态的,对于实例启动慢的服务器权重会在运行中调整。

3、static-rr
    每个服务器根据权重轮流使用,类似roundrobin,但它是静态的,意味着运行时修改权限是无效的。另外,它对服务器的数量没有限制。(该算法一般不用)

4、source
    对请求源IP地址进行哈希,用可用服务器的权重总数除以哈希值,根据结果进行分配。只要服务器正常,同一个客户端IP地址总是访问同一个服务器。如果哈希的结果随可用服务器数量而变化,那么客户端会定向到不同的服务器。(算法一般用于不能插入cookie的Tcp模式。它还可以用于广域网上为拒绝使用会话cookie的客户端提供最有效的粘连)
    该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

5、uri
    表示根据请求的URI左端(问号之前)进行哈希,用可用服务器的权重总数除以哈希值,根据结果进行分配。只要服务器正常,同一个URI地址总是访问同一个服务器。一般用于代理缓存和反病毒代理,以最大限度的提高缓存的命中率。该算法只能用于HTTP后端。(该算法一般用于后端是缓存服务器)
    该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

6、url_param
    在HTTP GET请求的查询串中查找<param>中指定的URL参数,基本上可以锁定使用特制的URL到特定的负载均衡器节点的要求。(该算法一般用于将同一个用户的信息发送到同一个后端服务器)
    该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

7、hdr(name)
    在每个HTTP请求中查找HTTP头<name>,HTTP头<name>将被看作在每个HTTP请求,并针对特定的节点。(如果缺少头或者头没有任何值,则用roundrobin代替)
    该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

8、rdp-cookie(name)
    为每个进来的TCP请求查询并哈希RDP cookie<name>。(该机制用于退化的持久模式,可以使同一个用户或者同一个会话ID总是发送给同一台服务器。如果没有cookie,则使用roundrobin算法代替)
    该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

docker镜像下载

docker pull gongfuxiang/haproxy

阅读全文

redis分布式缓存搭建与使用
发表于 2017-6-11 | 浏览(18318) | 服务器

redis官网地址 https://redis.io/

准备6台redis服务

127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
127.0.0.1:7004
127.0.0.1:7005

下载安装redis

mkdir /data
cd /data
mkdir src soft
cd /data/src/
wget http://download.redis.io/releases/redis-3.2.9.tar.gz
tar -zxvf redis-3.2.9.tar.gz
cd redis-3.2.9
make
make install

创建集群位置

cd /data/soft
mkdir redis-cluster
cd redis-cluster
mkdir 7000 7001 7002 7003 7004 7005

拷贝配置文件

cp /data/src/redis-3.2.9/redis.conf /data/soft/redis-cluster/7000
cp /data/src/redis-3.2.9/src/redis-trib.rb /data/soft/redis-cluster/

修改配置文件

cd /data/soft/redis-cluster/7000
vim redis.conf 修改以下选项内容

port 7000
daemonize yes  # 后台启动
cluster-enabled yes
cluster-config-file nodes.conf  # 指定集群节点配置文件
cluster-node-timeout 5000  # 指定集群节点超时时间
appendonly yes  # 指定持久化方式

完成后分别把 redis.conf 文件拷贝到7000 ~ 7005目录下,修改 port 对应目录名称的端口号

完成后分别启动6个实例

重启需要先删除数据文件和节点配置文件

for((i=0;i<=5;i++)); do cd /data/soft/redis-cluster/700$i/;rm -rf appendonly.aof  dump.rdb nodes.conf; done

循环启动redis

for((i=0;i<=5;i++)); do cd /data/soft/redis-cluster/700$i/; redis-server redis.conf; done

创建集群

/data/soft/redis-cluster/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

循环停止redis服务

for((i=0;i<=5;i++)); do redis-cli -c -p 700$i shutdown; done

启动redis服务,启动完成后查看实例列表 [ ps -ef | grep redis ],如下显示则说明启动成功

ps -ef | grep redis

root      32631      1  0 15:39 ?        00:00:00 redis-server 127.0.0.1:7000 [cluster]
root      32668      1  0 15:40 ?        00:00:00 redis-server 127.0.0.1:7001 [cluster]
root      32675      1  0 15:40 ?        00:00:00 redis-server 127.0.0.1:7002 [cluster]
root      32682      1  0 15:41 ?        00:00:00 redis-server 127.0.0.1:7003 [cluster]
root      32687      1  0 15:41 ?        00:00:00 redis-server 127.0.0.1:7004 [cluster]
root      32696      1  1 15:41 ?        00:00:00 redis-server 127.0.0.1:7005 [cluster]

安装ruby,由于redis集群客户端实现很少,redis集群的启动需要用到ruby实现的redis-trib.rb,所以我们需要先安装ruby。

yum -y install ruby

安装gem

yum -y install rubygems

gem 安装 redis ruby 接口

gem install redis

创建redis集群

--replicas 则指定了为 Redis Cluster 中的每个 Master 节点配备几个 Slave 节 点,节点角色由顺序决定,先 master 之后是 slave

/data/soft/redis-cluster/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
M: 443adf2c1d13b41866dc0dc108ffe858d931ac77 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: d74ee0110d7bcf0858ca76eb32caeca5094fa5ff 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: 13fd8b25f070382657c700fc9d8184418a82f8b6 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
S: 229a83d4997539771bf6792455c992cd215b7273 127.0.0.1:7003
   replicates 443adf2c1d13b41866dc0dc108ffe858d931ac77
S: 179a946b3ab66fac33d19316076e8c93d607a53a 127.0.0.1:7004
   replicates d74ee0110d7bcf0858ca76eb32caeca5094fa5ff
S: f6894bfcca6a22f426722a9b9843ba95cd20bb53 127.0.0.1:7005
   replicates 13fd8b25f070382657c700fc9d8184418a82f8b6
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join.
....
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 443adf2c1d13b41866dc0dc108ffe858d931ac77 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: d74ee0110d7bcf0858ca76eb32caeca5094fa5ff 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: 13fd8b25f070382657c700fc9d8184418a82f8b6 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 229a83d4997539771bf6792455c992cd215b7273 127.0.0.1:7003
   slots: (0 slots) slave
   replicates 443adf2c1d13b41866dc0dc108ffe858d931ac77
S: f6894bfcca6a22f426722a9b9843ba95cd20bb53 127.0.0.1:7005
   slots: (0 slots) slave
   replicates 13fd8b25f070382657c700fc9d8184418a82f8b6
S: 179a946b3ab66fac33d19316076e8c93d607a53a 127.0.0.1:7004
   slots: (0 slots) slave
   replicates d74ee0110d7bcf0858ca76eb32caeca5094fa5ff
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

这里输入 [ yes ] 如下
Can I set the above configuration? (type 'yes' to accept): yes

检查集群 状态

/data/soft/redis-cluster/redis-trib.rb check 127.0.0.1:7000

>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 443adf2c1d13b41866dc0dc108ffe858d931ac77 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: d74ee0110d7bcf0858ca76eb32caeca5094fa5ff 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: 13fd8b25f070382657c700fc9d8184418a82f8b6 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 229a83d4997539771bf6792455c992cd215b7273 127.0.0.1:7003
   slots: (0 slots) slave
   replicates 443adf2c1d13b41866dc0dc108ffe858d931ac77
S: f6894bfcca6a22f426722a9b9843ba95cd20bb53 127.0.0.1:7005
   slots: (0 slots) slave
   replicates 13fd8b25f070382657c700fc9d8184418a82f8b6
S: 179a946b3ab66fac33d19316076e8c93d607a53a 127.0.0.1:7004
   slots: (0 slots) slave
   replicates d74ee0110d7bcf0858ca76eb32caeca5094fa5ff
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

连接redis服务测试一下

[root@My src]# redis-cli -c -p 7000
127.0.0.1:7000> set name 200
-> Redirected to slot [5798] located at 127.0.0.1:7001
OK
127.0.0.1:7001> set devil mogui
-> Redirected to slot [893] located at 127.0.0.1:7000
OK
127.0.0.1:7000> get devil
"mogui"
127.0.0.1:7000> quit
[root@My src]# redis-cli -c -p 7003
127.0.0.1:7003> get devil
-> Redirected to slot [893] located at 127.0.0.1:7000
"mogui"
127.0.0.1:7000> 
127.0.0.1:7000> quit
[root@My src]# redis-cli -c -p 7002
127.0.0.1:7002> get name
-> Redirected to slot [5798] located at 127.0.0.1:7001
"200"
127.0.0.1:7001> get devil
-> Redirected to slot [893] located at 127.0.0.1:7000
"mogui"
127.0.0.1:7000> set age 20
OK
127.0.0.1:7000> quit
[root@My src]# redis-cli -c -p 7005
127.0.0.1:7005> get age
-> Redirected to slot [741] located at 127.0.0.1:7000
"20"
127.0.0.1:7000> set sex 30
OK
127.0.0.1:7000> quit
[root@My src]# redis-cli -c -p 7001
127.0.0.1:7001> get sex
-> Redirected to slot [2584] located at 127.0.0.1:7000
"30"
127.0.0.1:7000>

使用add-node命令来添加节点,第一个参数是新节点的地址,第二个参数是任意一个已经存在的节点的IP和端口

添加一个从节点,使用[ --slave ] 参数

/data/soft/redis-cluster/redis-trib.rb add-node --slave 127.0.0.1:7007 127.0.0.1:7000

添加从节点还可以指定这个从节点的主节点id,使用[ --master-id ] 参数指定masterid

/data/soft/redis-cluster/redis-trib.rb add-node --slave --master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7007 127.0.0.1:7000

重新分配哈希槽

/data/soft/redis-cluster/redis-trib.rb reshard 127.0.0.1:7006

移除一个节点,第一个参数是集群中的任意一个节点地址,第二个是需要移除的节点id(移除前请确保节点哈希槽数量是空的)当移除一个master节点的时候,如果节点有哈希槽则失败

/data/soft/redis-cluster/redis-trib.rb del-node 127.0.0.1:7000 fea8868aeb4ce79d447b602e1cf07b4318adb852

改变从节点的主节点id[ CLUSTER REPLICATE <master-node-id> ](如把7007的主节点id改成7001的id)

[root@My redis-cluster]# redis-cli -c -p 7007
127.0.0.1:7007> cluster replicate cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf
OK


添加一个新节点演示

cd /data/soft/redis-cluster/
cp -r 7005 7006
cd 7006
rm -rf dump.rdb appendonly.aof nodes.conf
vim redis.conf # 修改7005为7006保存
redis-server redis.conf

使用add-node命令来添加节点,第一个参数是新节点的地址,第二个参数是任意一个已经存在的节点的IP和端口. 我们可以看到新的节点已经添加到集群中

/data/soft/redis-cluster/redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

查看7006节点是否正常加入了集群(可以看出 7006 成为了master节点,但是还未分配哈希槽)

[root@My redis-cluster]# redis-cli -p 7000 cluster nodes

e3cb1f4805d31dc0dc11b1e5539653b2c4144216 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
c7a0afa1c64045bad02de7478cc23f1d65a3b035 127.0.0.1:7006 master - 0 1497061063704 0 connected
64d1a9e01ca3820288c7e5c4adc3a161b7816895 127.0.0.1:7005 slave 20c27ce2235485f2d5aa5d941674d7f81ee22682 0 1497061064812 6 connected
dffe09f5b1739dc5b53f8299d20b06508eccb15d 127.0.0.1:7004 slave cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 0 1497061065820 5 connected
20c27ce2235485f2d5aa5d941674d7f81ee22682 127.0.0.1:7002 master - 0 1497061064309 3 connected 10923-16383
cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 127.0.0.1:7001 master - 0 1497061065316 2 connected 5461-10922
3f363ffcacfa225ee098819b67ab4bd5d0e5def8 127.0.0.1:7003 slave e3cb1f4805d31dc0dc11b1e5539653b2c4144216 0 1497061063805 4 connected

给7006分配哈希槽

[root@My redis-cluster]# /data/soft/redis-cluster/redis-trib.rb reshard 127.0.0.1:7006

How many slots do you want to move (from 1 to 16384)? 需要分配的哈希槽数量 如:100
What is the receiving node ID? 7006节点的ID 如:c7a0afa1c64045bad02de7478cc23f1d65a3b035
Source node #1:需要从哪个节点分配哈希槽,all则从所有master节点上随机凑100个哈希槽。或者输入节点ID换行以done结束。如输入7001的节点id:cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf
Source node #2:done
Do you want to proceed with the proposed reshard plan (yes/no)? 打印被移动的 slot 后,输入 yes 开始移动 slot 以及对应的数据

哈希槽分配完成,可以看出7006刚好100个哈希槽数量,7001也刚好少了100个哈希槽

[root@My redis-cluster]# redis-cli -p 7000 cluster nodes

e3cb1f4805d31dc0dc11b1e5539653b2c4144216 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
c7a0afa1c64045bad02de7478cc23f1d65a3b035 127.0.0.1:7006 master - 0 1497061327609 7 connected 5461-5560
64d1a9e01ca3820288c7e5c4adc3a161b7816895 127.0.0.1:7005 slave 20c27ce2235485f2d5aa5d941674d7f81ee22682 0 1497061325594 6 connected
dffe09f5b1739dc5b53f8299d20b06508eccb15d 127.0.0.1:7004 slave cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 0 1497061327609 5 connected
20c27ce2235485f2d5aa5d941674d7f81ee22682 127.0.0.1:7002 master - 0 1497061326097 3 connected 10923-16383
cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 127.0.0.1:7001 master - 0 1497061327106 2 connected 5561-10922
3f363ffcacfa225ee098819b67ab4bd5d0e5def8 127.0.0.1:7003 slave e3cb1f4805d31dc0dc11b1e5539653b2c4144216 0 1497061326602 4 connected

当移除一个master节点的时候,不能有哈希槽数量(把当7002前master节点的哈希槽转移到7006节点上去)

[root@My redis-cluster]# ./redis-trib.rb reshard 127.0.0.1:7002
How many slots do you want to move (from 1 to 16384)? 输入7002的哈希槽数量,16383-10923如:5461
What is the receiving node ID? 输入7006的id,如:c7a0afa1c64045bad02de7478cc23f1d65a3b035
Source node #1: 从哪个节点分配哈希槽,这里输入7002的id,ID换行以done结束如:20c27ce2235485f2d5aa5d941674d7f81ee22682
Source node #2:done
Do you want to proceed with the proposed reshard plan (yes/no)? 打印被移动的 slot 后,输入 yes 开始移动 slot 以及对应的数据

查看7002集群状态,由此可以看到7002节点已经没有哈希槽数量了,而7006已经多了5461个哈希槽数[ 10923-16383 ]

[root@My redis-cluster]# redis-cli -p 7000 cluster nodes
e3cb1f4805d31dc0dc11b1e5539653b2c4144216 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
c7a0afa1c64045bad02de7478cc23f1d65a3b035 127.0.0.1:7006 master - 0 1497070326503 7 connected 5461-5560 10923-16383
64d1a9e01ca3820288c7e5c4adc3a161b7816895 127.0.0.1:7005 slave c7a0afa1c64045bad02de7478cc23f1d65a3b035 0 1497070326000 7 connected
dffe09f5b1739dc5b53f8299d20b06508eccb15d 127.0.0.1:7004 slave cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 0 1497070327004 5 connected
20c27ce2235485f2d5aa5d941674d7f81ee22682 127.0.0.1:7002 master - 0 1497070326000 3 connected
cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 127.0.0.1:7001 master - 0 1497070327507 2 connected 5561-10922
3f363ffcacfa225ee098819b67ab4bd5d0e5def8 127.0.0.1:7003 slave e3cb1f4805d31dc0dc11b1e5539653b2c4144216 0 1497070327004 4 connected

从集群中移除7002节点

[root@My redis-cluster]# ./redis-trib.rb del-node 127.0.0.1:7000 20c27ce2235485f2d5aa5d941674d7f81ee22682
>>> Removing node 20c27ce2235485f2d5aa5d941674d7f81ee22682 from cluster 127.0.0.1:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

查看7002已经不在集群中了,原来的哈希槽已由7006接手,当前集群的数据也是不会受到任何影响

[root@My redis-cluster]# redis-cli -p 7000 cluster nodes
e3cb1f4805d31dc0dc11b1e5539653b2c4144216 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
c7a0afa1c64045bad02de7478cc23f1d65a3b035 127.0.0.1:7006 master - 0 1497070633845 7 connected 5461-5560 10923-16383
64d1a9e01ca3820288c7e5c4adc3a161b7816895 127.0.0.1:7005 slave c7a0afa1c64045bad02de7478cc23f1d65a3b035 0 1497070634348 7 connected
dffe09f5b1739dc5b53f8299d20b06508eccb15d 127.0.0.1:7004 slave cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 0 1497070633343 5 connected
cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 127.0.0.1:7001 master - 0 1497070632843 2 connected 5561-10922
3f363ffcacfa225ee098819b67ab4bd5d0e5def8 127.0.0.1:7003 slave e3cb1f4805d31dc0dc11b1e5539653b2c4144216 0 1497070632340 4 connected

添加7002为master,7007为slave两个节点(可以看出7002为master还未分配哈希槽,7007为slave)

[root@My redis-cluster]# ./redis-trib.rb add-node 127.0.0.1:7002 127.0.0.1:7000
[root@My redis-cluster]# ./redis-trib.rb add-node --slave 127.0.0.1:7007 127.0.0.1:7000

[root@My redis-cluster]# redis-cli -p 7000 cluster nodes
e3cb1f4805d31dc0dc11b1e5539653b2c4144216 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
c7a0afa1c64045bad02de7478cc23f1d65a3b035 127.0.0.1:7006 master - 0 1497078346719 7 connected 5461-5560 10923-16383
64d1a9e01ca3820288c7e5c4adc3a161b7816895 127.0.0.1:7005 slave c7a0afa1c64045bad02de7478cc23f1d65a3b035 0 1497078346216 7 connected
dffe09f5b1739dc5b53f8299d20b06508eccb15d 127.0.0.1:7004 slave cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 0 1497078347221 5 connected
bde1b4378b10c6c7fbb8ba62189fc4d8fbbc6da7 127.0.0.1:7007 slave a7aeb2c3bef177ff671c5304d3baf0a825025d3c 0 1497078347723 0 connected
cba8ca301ef0fc8039af8313d580b0a5bc8ea8cf 127.0.0.1:7001 master - 0 1497078347221 2 connected 5561-10922
a7aeb2c3bef177ff671c5304d3baf0a825025d3c 127.0.0.1:7002 master - 0 1497078346719 0 connected
3f363ffcacfa225ee098819b67ab4bd5d0e5def8 127.0.0.1:7003 slave e3cb1f4805d31dc0dc11b1e5539653b2c4144216 0 1497078348226 4 connected

把7002节点从集群中移除(7002还未分配哈希槽数量,所以可以直接移除成功)

[root@My redis-cluster]# ./redis-trib.rb del-node 127.0.0.1:7000 a7aeb2c3bef177ff671c5304d3baf0a825025d3c
>>> Removing node a7aeb2c3bef177ff671c5304d3baf0a825025d3c from cluster 127.0.0.1:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> 127.0.0.1:7007 as replica of 127.0.0.1:7000
>>> SHUTDOWN the node.

把7007节点中添加点数据

[root@My redis-cluster]# ./redis-trib.rb del-node 127.0.0.1:7000 bde1b4378b10c6c7fbb8ba62189fc4d8fbbc6da7
>>> Removing node bde1b4378b10c6c7fbb8ba62189fc4d8fbbc6da7 from cluster 127.0.0.1:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

PHP中使用方式

<?php

$redis = new RedisCluster(null, ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7002', '127.0.0.1:7003', '127.0.0.1:7004', '127.0.0.1:7005']);
var_dump($redis->set('gong', 'gongfuxiang'));
var_dump($redis->set('xxx', 'XIANG'));
var_dump($redis->get('devil'));
var_dump($redis->get('sex'));
var_dump($redis->get('age'));
var_dump($redis->get('ggg'));
var_dump($redis->get('ppp'));
?>

docker镜像下载

docker pull gongfuxiang/centos7.3-redis-cluster

阅读全文

Centos7下配置php-fpm启动服务脚本
发表于 2017-5-29 | 浏览(14441) | 服务器

新增配置文件,根据自己安装的php-fpm路径修改   vim /usr/lib/systemd/system/php-fpm.service

[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target

[Service]
Type=simple
PIDFILE=/data/soft/php56/var/run/php-fpm.pid
ExecStart=/data/soft/php56/sbin/php-fpm --nodaemonize --fpm-config /data/soft/php56/etc/php-fpm.conf
ExecRestart=/bin/kill -USR2 $PIDFILE
ExecStop=/bin/kill -SIGINT $PIDFILE

[Install]
WantedBy=multi-user.target

增加开机启动

systemctl enable php-fpm.service

操作命令

启动
systemctl start php-fpm.service 

停止
systemctl stop php-fpm.service 

重启
systemctl restart php-fpm.service 

阅读全文

Centos7下配置nginx启动服务脚本
发表于 2017-5-29 | 浏览(12644) | 服务器

1:nginx配置文件,nginx路径根据自己安装的位置而修改  vim /etc/init.d/nginx

#! /bin/bash
#chkconfig: 2345 80 90
#description:nginx run

# nginx启动脚本
# @author   Devil
# @version  0.0.1
# @date     2017-05-29

PATH=/data/soft/nginx
DESC="nginx daemon"
NAME=nginx
DAEMON=$PATH/$NAME
CONFIGFILE=$PATH/$NAME.conf
PIDFILE=$PATH/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
set -e
[ -x "$DAEMON" ] || exit 0
do_start()
{
    $DAEMON -c $CONFIGFILE || echo -n "nginx already running"
}
do_stop()
{
    $DAEMON -s stop || echo -n "nginx not running"
}
do_reload()
{
    $DAEMON -s reload || echo -n "nginx can't reload"
}
case "$1" in
    start)
        echo -n "Starting $DESC: $NAME"
        do_start
        echo "."
    ;;
    stop)
        echo -n "Stopping $DESC: $NAME"
        do_stop
        echo "."
    ;;
    reload|graceful)
        echo -n "Reloading $DESC configuration..."
        do_reload
        echo "."
    ;;
    restart)
        echo -n "Restarting $DESC: $NAME"
        do_stop
        do_start
        echo "."
    ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" >&2
        exit 3
    ;;
esac
exit 0

2:设置执行权限

chmod a+x /etc/init.d/nginx

3:注册成服务

chkconfig --add nginx

4:设置开机启动

chkconfig nginx on

5:重启, 查看nginx服务是否自动启动

shutdown -h 0 -r

ps -ef | grep nginx

6:对nginx服务执行停止/启动/重新读取配置文件操作

启动
systemctl start nginx.service

重载
systemctl reload nginx.service

停止
systemctl top nginx.service

重启
systemctl restart nginx.service

阅读全文

CentOS安装netdata监控服务器
发表于 2017-5-19 | 浏览(12849) | 服务器

效果图

Image

安装一些依赖包

yum -y install zlib-devel libuuid-devel libmnl-devel gcc make git autoconf autogen automake pkgconfig

安装netdata

mkdir -p /data/src
cd /data/src
git clone https://github.com/firehol/netdata.git
./netdata-installer.sh 

查看端口是否已经运行(如果存在netdata记录就不需要再次启动了)

netstat -ntlp | grep 19999

启动netdata(默认安装完成就已经启动了)

/usr/sbin/netdata

配置web访问,采用nginx反向代理(创建 netdata.conf 完成后重载nginx)

upstream backend {  
    server 127.0.0.1:19999;
    keepalive 64;
}

server {  
    listen      80;
    server_name netdata.gong.gg;

    location / {  
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_pass_request_headers on;
        proxy_set_header Connection "keep-alive";
        proxy_store off;
    }
}

配置完成,访问查看监控信息

http://netdata.gong.gg/

1、放开防火墙 19999 端口,netdata会自动拉取该端口的服务器列表

2、netdata访问是没有限制的,我们使用htpasswd需要用户名和密码才能访问,参考博客中 htpasswd 的教程

阅读全文

CentOS下PHP7安装Redis扩展
发表于 2017-5-18 | 浏览(9006) | 服务器

下载扩展包

wget https://github.com/phpredis/phpredis/archive/php7.zip
mv php7.zip phpredis-php7.zip
unzip phpredis-php7.zip
cd phpredis-php7/
/data/soft/php7/bin/phpize
./configure --with-php-config=/data/soft/php7/bin/php-config
make && make install

php.ini中添加redis扩展

vim /data/soft/php7/lib/php.ini 
搜索 extension 在底部添加 redis 扩展记录
extension=redis.so

重启php-fpm后,查看扩展

/data/soft/php7/bin/php -m

阅读全文

CentOS安装PHP7
发表于 2017-5-18 | 浏览(7641) | 服务器

创建软件目录

mkdir -p /data/soft/php7

创建用户和用户组

groupadd www-data
useradd -g www-data www-data

安装PHP7,下载地址从php官网获取

wget http://cn2.php.net/distributions/php-7.1.5.tar.gz
tar -zxvf php-7.1.5.tar.gz
cd php-7.1.5
./configure --prefix=/data/soft/php7 --enable-fpm --with-mcrypt \--enable-mbstring --disable-pdo --with-curl --disable-debug  --disable-rpath \--enable-inline-optimization --with-bz2  --with-zlib --enable-sockets \--enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex \--with-mhash --enable-zip --with-pcre-regex --with-mysql --with-mysqli \--with-gd --with-jpeg-dir --enable-pdo --enable-ftp --with-pdo_sqlite --with-openssl=/usr/local/ssl/ --with-pdo_mysql
make && make install

配置文件添加

cp php.ini-development /data/soft/php7/lib/php.ini
cd /data/soft/php7/etc
cp php-fpm.conf.default php-fpm.conf
cd php-fpm.d cp www.conf.default www.conf

修改 www.conf

user = www-data
group = www-data

修改 php-fpm.conf

cd /data/soft/php7/etc
vim php-fpm.conf
去掉 pid = run/php-fpm.pid 前面的分号 [ ; ]

启动PHP即可

/data/soft/php7/sbin/php-fpm

阅读全文

一次服务器高峰期宕机排查经历
发表于 2016-12-14 | 浏览(9961) | 服务器

服务器配置与环境

系统:CentOS7
内存:16G
CPU:8核
磁盘:两块(100G, 1T)
mysql:MySQL5.7
php:PHP5.6
带宽:10兆

将近百万访问量,每天上午9点左右和晚上10点左右必定会宕机。每次重启服务器后问题都没有了,没法知道具体是那块所造成。开始仔细想问题在那边,H5新闻站点基本上都是使用搜索引擎运行的,包括后来我开发的PC站点全部采用搜索引擎运行,不会有任何数据库操作。以为是mysql配置需要优化,所以就开始做起了服务器优化。

1、第一看见就是服务器IO过高造成了宕机,经过排查是mysql所占用,开始调整H5项目把直接操作数据库的部分都改成搜索引擎。重启后通过mysql命令行 show processlist; 查看正常,怀疑这个时候是脚本没运行,所以查不到问题了。

2、为了不影响业务运作,把线上有收益的业务迁移到其它服务器。磁盘重新分布,图片,数据库,搜索引擎全部分开,发现mysql磁盘过高,由此可以完全定位IO过高和mysql脱不了一点干系。

3、开始做mysql配置优化,不能让服务器宕机,经过两天的调试,服务器不宕机了,IO还是能够达到80%以上。平时偶尔也发现IO也不小。开始头疼了应用程序和服务器都优化了还是不见有个好的效果。

4、持续观察IO状况,在IO高的时候排查mysql,发现有部分sql运行时间都是在30秒以上,IO都是读的负载过高,肯定是这个原因导致的,这条sql所使用的字段没有索引,加上索引后,IO明显下降到5%左右。

5、当时心里非常激动,花了两天调试服务器各种配置优化。结果发现饶了这么大一个弯。最终还是因为mysql索引优化问题,最终问题还是出现在爬虫上面,每次爬虫跑的时候都会比对数据,再数据表越来越大的时候,字段没有索引就慢如蜗牛。虽然绕弯了还是有很大的收获的,在各种配置优化上也更明白的认识到了很多场景的优化方式。

6、很多时候都是本地开发好的项目,怎么玩都正常,只要上线都会有点问题,运营一段时间后问题也越来越多,这都是没有考虑到很多因素的问题。

阅读全文

Linux监控http服务是否正常
发表于 2016-12-7 | 浏览(8471) | 服务器

使用定时任务定时校验是否正确,如果状态不正常,则发送邮件通知,邮件发送服务可以搜索本博客中的文章。

添加文件 vim http_mog.sh   内容如下

#!/bin/bash

#@author:Devil
#@desc:监控http服务是否正常
#@blog:http://gong.gg/
#@date:2016-12-07

HTTP_CODE=`curl -I -m 10 -o /dev/null -s -w %{http_code}"\n" gong.gg`

# 不等于200则发送邮件
if [ $HTTP_CODE != 200 ]
then
    echo "亲^_^!你的服务器好像不乖了哦,状态码:[${HTTP_CODE}] ,请尽快处理哦~" | mail -v -s '服务器HTTP监控' devil@gong.gg
fi

阅读全文

TOP