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, 应该姿势正确吧.

浅谈Java开发中Redis的使用姿势

- - 尚弟的小笔记
Redis是我们开发时最常使用的键值存储工具了,但是与诸多软件工具一样,它也有很多技巧和经验. 本文就是将我了解的一些经验和教训分享出来. 如果不谨慎使用Redis,可能浪费大量的内存,甚至性能低下. 以下时 使用时的几个具体建议:. 通常一个Redis实例有16个数据库,通常你的业务并不是独立的数据库.

花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命令进行删除是无效的.

连接池连接HBase的正确姿势

- -
在云HBase值班的时候,经常会遇见有用户咨询诸如“HBase是否支持连接池. ”这样的问题,也有用户因为应用中创建的Connection对象过多,触发了zookeeper的连接数限制,导致客户端连不上的. 究其原因,都是因为对HBase客户端的原理不了解造成的. 本文简单介绍HBase客户端的Connection对象与socket连接的关系,并给出Connection的正确用法.

Kubernetes API探索之旅的正确姿势

- - DockOne.io
【编者的话】本文带你打开Kubernetes API的探索之旅的正确姿势,快来一睹为快吧. 使用CLI(如curl)或GUI(如postman)HTTP客户端调用Kubernetes API有很多理由. 例如,你可能需要对Kubernetes 对象进行比kubectl提供的更细粒度的控制,或者只是想在尝试从代码访问API之前探索它.

很强,我终于找到绘制E-R图的正确姿势!

- - 掘金 后端
不知道大家是不是和我一样,为了追求速度,开发时一般都是直接建表就干,哪管什么E-R图. 直到xxx项目找上你,某某客户要E-R图,提供一下吧. 这时候就很烦,从头绘制E-R图成本真的很高,今天我就遇到了这个糟心事. 那有什么办法快速从我们的DDL建表语句直接反向生成我们的E-R图呢. 如何做到即便新版本表结构发生变化,也能够在原来的基础上做简单增量修改即可满足呢.