前言面试
说到分布式缓存,可能大多数人脑海浮现的就是redis了,为何redis可以在竞争激烈的缓存大战中脱颖而出呢?缘由无非有一下几点:性能好,丰富的特性跟数据结构,api操做简单。可是用的人多了,就会出现不少不规范或者疏忽的地方,严重的时候甚至会致使生产事故,因此咱们有必要来聊聊在Redis使用过程当中的一些“正确姿式“。redis
切忌裸奔shell
你们别笑... 不少初学者或者没经验的开发人员在服务器上用root用户装了redis之后,打开默认端口直接就愉快的运行起来了,开放了外网及默认端口的链接,甚至对于生产环境也这样,贪图一时的方便,这种状况比较多的出如今一些初创公司 (包括N年前的我也这么干过...)数据库
那么会出现什么问题呢?最多见的就是Redis未受权访问漏洞。攻击者扫描到互联网开放的ip以及默认的6379端口后,直接在本地远程链接你服务器的redis,经过redis的命令将本机生成的公钥写入到服务器的authorized.keys中,这时候本机就能够ssh免密登陆进来了。接下来能够写入反弹shell,提权,而后就能够随心所欲了,这就是为何你的服务器上面会忽然出现有挖矿程序的一个缘由。api
为了防止出现上述的风险,咱们能够从如下几个地方来处理。缓存
说到这个,笔者也是满满的泪,在年少无知的时候曾经在生产环境执行过这个命令,后来差点收拾背包提早下班了。为何这个操做这么可怕呢?“key *” 操做的意思是返回数据库中全部匹配的key,它会扫一次性扫描全部的记录,当你库里的数据量很大的时候,会形成redis的阻塞,cpu使用率飙升,慢慢的拖垮项目中对redis的相关请求直至出现各类timeout...安全
在Redis2.8版本之后,提供了一个更好的遍历key的操做"scan",它相似于咱们jdbc中ResultSet,经过一个游标来迭代。使用方法为“SCAN cursor [MATCH pattern] [COUNT count]”。服务器
redis 127.0.0.1:6379> scan 0 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" redis 127.0.0.1:6379> scan 17 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设计能够参照咱们的关系型数据库。ssh
假若有一个user表,有userid,age,username字段,那么咱们key就能够"user:userid:useridValue:username"这么来设计,把表名做为key的前缀,查询的条件放在最后。中间用字段跟它所对应的value分割开来,全部的设计都是为了在查询的时候能够更便捷。
redis的db下标默认0-15,也就是有16个。一般大部分人都是使用db0,全部的k-v都在一个库中。这其实没多大问题,可是redis不是关系型数据库,存储的数据相互耦合不那么大,因此建议能够按照不一样的业务把数据分散到各个库中,这样咱们能够select 不一样的 db 来执行不一样的业务模块操做。
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文章