Redis 的正确使用姿势

标签: dev | 发表时间:2019-03-30 00:00 | 作者:
出处:http://itindex.net/relian


前言


说到分布式缓存,可能大多数人脑海浮现的就是redis了,为什么redis能够在竞争激烈的缓存大战中脱颖而出呢?原因无非有一下几点:性能好,丰富的特性跟数据结构,api操作简单。但是用的人多了,就会出现很多不规范或者疏忽的地方,严重的时候甚至会导致生产事故,所以我们有必要来聊聊在Redis使用过程中的一些“正确姿势“。



切忌裸奔


大家别笑... 很多初学者或者没经验的开发人员在服务器上用root用户装了redis以后,打开默认端口直接就愉快的运行起来了,开放了外网及默认端口的连接,甚至对于生产环境也这样,贪图一时的方便,这种情况比较多的出现在一些初创公司 (包括N年前的我也这么干过...)


那么会出现什么问题呢?最常见的就是Redis未授权访问漏洞。攻击者扫描到互联网开放的ip以及默认的6379端口后,直接在本地远程连接你服务器的redis,通过redis的命令将本机生成的公钥写入到服务器的authorized.keys中,这时候本机就可以ssh免密登录进来了。接下来可以写入反弹shell,提权,然后就可以为所欲为了,这就是为什么你的服务器上面会突然出现有挖矿程序的一个原因。


为了防止出现上述的风险,我们可以从以下几个地方来处理。

  • 修改默认端口6379

  • 绑定内网访问 bing 127.0.0.1

  • 添加redis的密码验证

  • 以低权限的用户运行redis

  • 必要时设置防火墙策略



禁止“ key *” ,用“scan”代替


说到这个,笔者也是满满的泪,在年少无知的时候曾经在生产环境执行过这个命令,后来差点收拾背包提前下班了。为什么这个操作这么可怕呢?“key *” 操作的意思是返回数据库中所有匹配的key,它会扫一次性扫描所有的记录,当你库里的数据量很大的时候,会造成redis的阻塞,cpu使用率飙升,慢慢的拖垮项目中对redis的相关请求直至出现各种timeout...


在Redis2.8版本以后,提供了一个更好的遍历key的操作"scan",它类似于我们jdbc中ResultSet,通过一个游标来迭代。使用方法为“SCANcursor[MATCH pattern][COUNT count]”。


   redis127.0.0.1:6379>scan0   1) "17"   2)  1) "key:12"   2) "key:8"   3) "key:4"   4) "key:14"   5) "key:16"   6) "key:17"   7) "key:15"   8) "key:10"   9) "key:3"   10) "key:7"   11) "key:1"       
redis127.0.0.1:6379>scan17 1) "0" 2) 1) "key:5" 2) "key:18" 3) "key:0" 4) "key:2" 5) "key:19" 6) "key:13" 7) "key:6" 8) "key:9" 9) "key:11"


“scan 0 ”表示开始一个新的迭代,当返回的第一参数为0时,则表示迭代结束,若不为0,下一次迭代的时候带上这个游标开始下一次遍历,直到返回0.第二个参数则是当前遍历出来的值。使用的时候需要注意版本,当版本低于2.8时,需升级才能使用。


key的设计


首先用“:”来分割key是一个约定俗成的东西,自己使用的时候就尽量不要用一些比较特殊的字符来代替。关于我们的key设计可以参照我们的关系型数据库。


假如有一个user表,有userid,age,username字段,那么我们key就可以"user:userid:useridValue:username"这么来设计,把表名作为key的前缀,查询的条件放在最后。中间用字段跟它所对应的value分割开来,所有的设计都是为了在查询的时候可以更便捷。


合理使用多个db


redis的db下标默认0-15,也就是有16个。通常大部分人都是使用db0,所有的k-v都在一个库中。这其实没多大问题,但是redis不是关系型数据库,存储的数据相互耦合不那么大,所以建议可以按照不同的业务把数据分散到各个库中,这样我们可以select 不同的 db 来执行不同的业务模块操作。


善用5种数据结构


redis提供了5种数据结构,但是根据以往的面试结果来看,很多应聘者几乎在项目中只用到string类型,甚至对其他类型一知半解。其实当我们能在不同的场景善用不同的结构的话,效率会有很大的提升。下面简单介绍几个例子。


SortSet


它提供了一个优先级(score)来排序,我们可以把score的值设置成时间戳,这样我们可以通过一些定时的操作来取出某段时间里面数据,在我们项目的机器人模块中有大量的此类操作。还有常用的地方是排行榜,通过score值的变化来快速高效的更新榜单。


list


它的实现是一个双向链表,我们可以把一些需要执行的任务通过lpush,rpush存放进来,组成符合我们需求的顺序,最后我们在依次取出来执行,类似于mq。


set


用来做一些自动去重的操作,比如redis的交集命令,可以取出2个人的共同好友。


禁用高危命令


redis中有很多高危命令。如“flushdb”,“config”等,我们可以禁止或者重命名这些命令来使得操作更加安全。


我们需要修改redis的配置文件redis.conf,在SECURITY这一项中,新增

       rename-command FLUSHALL ""

       rename-command CONFIG ""

假如是重命名的话

       rename-command FLUSHALL abcdefg

配置完重启后生效。


结语

对于redis的话题,其实还有很多,比如发布订阅,持久化机制,集群等。很多最佳实践都需要结合自身的业务不断摸索,还是那句话,适合自己的才是最好的。



喜欢的话,关注一下公众号《 深夜里的程序猿》,每天更新高质量IT文章~


相关 [redis 正确 姿势] 推荐:

Redis 的正确使用姿势

- - IT瘾-dev
说到分布式缓存,可能大多数人脑海浮现的就是redis了,为什么redis能够在竞争激烈的缓存大战中脱颖而出呢. 原因无非有一下几点:性能好,丰富的特性跟数据结构,api操作简单. 但是用的人多了,就会出现很多不规范或者疏忽的地方,严重的时候甚至会导致生产事故,所以我们有必要来聊聊在Redis使用过程中的一些“正确姿势“.

在Linux进行IO的正确姿势

- - idea's blog
很多C/C++程序虽然在做网络编程, 但大多用别人封装好的库, 对底层不甚了解, 感觉 IO 操作不是很简单吗. 我敢说, 大多数人进行 IO 的姿势都不对, 所谓的 IO, 主要是 read()/write() 两个函数.. 先说错误的 IO 读操作:. 看起来好像很正确的样子, 返回值也判断了, 不仅判断 -1, 还判断 0, 应该姿势正确吧.

花2分钟了解正确的上网姿势

- Bob - 囧片王
用葛炮的话说是:我有姿势我自豪. 2分钟创意短片,告诉你正确的上网姿势,养成良好的习惯,以后就不会腰酸背痛手抽筋了:.

用正确的姿势避免后背疼痛

- 柯嘉 - 牛博山寨 编辑推荐
一提起身体姿势,妈妈总是知道得最多,她不厌其烦地提醒你要站直、别懒懒散散的,而这些都是正确的建议. But when you stoop or slouch, your muscles and ligaments struggle to keep you balanced — which can lead to fatigue, back pain, headaches and other problems.

如何用正确的姿势让你家的WiFi更安全?

- - 雷锋网
不管是你连入黑客的WiFi,还是黑客连入你的WiFi,最终结果可能都是一样的. 如果蹭你家网的人不安好心,电视中的画面可能会重演哦. 作为一个安全研究者,在物联网还没有这么火的时候就知道,物联网火起来的时候一定会存在网络安全问题. 任何一个新事物,在发展之初都会更多地考虑用户的使用感受,从而忽视一些其他的问题.

Linux下正确删除海量文件的姿势

- - WEB骇客
这里说的“海量”并不是指体积大,而是指数量,比如一个目录下有数百万个小文件. 最近在优化服务器时发现postfix下的maildrop目录和clientmqueue目录下发现有大量的文件,进入这些目录里使用ls命令是愚蠢的做法,而直接执行 rm *,没有任何反应,文件数量也没有减少,也就是说,在海量文件目录里直接使用rm命令进行删除是无效的.

Redis分布式锁的正确实现方式(Java版) - 吴大山的博客 | Wudashan Blog

- -
本博客使用第三方开源组件Jedis实现Redis客户端,且只考虑Redis服务端单机部署的场景. 分布式锁一般有三种实现方式:1. 基于ZooKeeper的分布式锁. 本篇博客将介绍第二种方式,基于Redis实现分布式锁. 虽然网上已经有各种介绍Redis分布式锁实现的博客,然而他们的实现却有着各种各样的问题,为了避免误人子弟,本篇博客将详细介绍如何正确地实现Redis分布式锁.

Redis 负载监控——redis-monitor

- - ITeye资讯频道
redis-monitor是一个Web可视化的 redis 监控程序. 使用 Flask 来开发的,代码结构非常简单,适合移植到公司内网使用. redis 服务器信息,包括 redis 版本、上线时间、 os 系统信息等等. 实时的消息处理信息,例如处理 command 数量、连接总数量等. 内存占用、 cpu 消耗实时动态图表.

Redis 起步

- - 博客园_首页
Rdis和JQuery一样是纯粹为应用而产生的,这里记录的是在CentOS 5.7上学习入门文章:. Redis是一个key-value存储系统. 和Memcached类似,但是解决了断电后数据完全丢失的情况,而且她支持更多无化的value类型,除了和string外,还支持lists(链表)、sets(集合)和zsets(有序集合)几种数据类型.

redis 配置

- - 谁主沉浮
# 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写). # 内存配置大小写是一样的.比如 1gb 1Gb 1GB 1gB. # daemonize no 默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes. # 当redis在后台运行的时候,Redis默认会把pid文件放在/var/run/redis.pid,你可以配置到其他地址.