redis学习杂记
Posted EZ4GodJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis学习杂记相关的知识,希望对你有一定的参考价值。
Redis
了解redis
redis是一种开源、使用c语言编写的、支持网络交互的,可基于内存也可以持久化的Key-Value数据库。
数据结构
Redis使用的数据结构如下:String、list、集合、有序集合、哈希,对于key的使用不应太长(尽量不要超过1024字节),造成消耗过多的内存,影响查找的效率,也不应过短影响key的可读性,对key应有统一的格式。
在使用string时,如果遇到数值操作,redis会将字符串类型转换为数值。
List的底层实现是链表,因此在首位插入元素的时间复杂度都是常数级的,list的常用操作为LPUSH、RPUSH、LRANGE。
Redis的集合分为有序集合与无序集合,其区别是有序集合每一个元素都关联一个序号。通常将无序集合称为set而有序集合为zset因为有序集合的操作都是以z为开头。
哈希是从redis-2.0.0版本之后才有的数据结构,存的是字符串和字符串值之间的映射,比如一个用户要存储其全名、姓氏、年龄等等,就很适合使用哈希。
持久化
Redis的持久化分为两种,分别为RDB(Redis DataBase)和AOF(Append Only File),若不进行持久化则redis将变为纯内存数据库。
RDB是一种快照式的持久化,即将某一时刻的数据持久化存入磁盘之中。进行持久化时,会先创建一个进程,建立一个临时文件,待持久化完成后再替换上次持久化好的文件。这种持久化下,每一个快照都是完整可用的,方便随时备份,缺点是这种方法存的是一个时刻的快照,时刻间均会产生间隔,若间隔太多会产生资源上的浪费,间隔太长出现问题就会流失大量的数据,因此还可以使用AOF持久化。
AOF是将redis经历过的所有写的指令记录下来,是只允许追加不允许改写的文件,AOF重写是会创建一个新的子进程,读取现有AOF文件存入临时文件,并将新接受的指令存入内存缓冲区,在保着原有AOF文件的同时避免重写过程出现意外,当重写结束时会提供给父进程一个信号,将内存缓冲区的新指令加入到新文件,追加结束后,就可以产生新的AOF文件替代旧文件,并由新AOF文件接受新的写指令。默认的AOF持久化策略是每秒钟fsync一次,通过一同使用RDB、AOF,即可产生更为可靠的持久化方案。
主从同步
像mysql一样,redis是支持主从同步的,而且也支持一主多从以及多级从结构。
主从结构,一是为了纯粹的冗余备份,二是为了提升读性能,比如很消耗性能的SORT就可以由从服务器来承担。
redis的主从同步是异步进行的,这意味着主从同步不会影响主逻辑,也不会降低redis的处理性能。
主从架构中,可以考虑关闭主服务器的数据持久化功能,只让从服务器进行持久化,这样可以提高主服务器的处理性能。
在主从架构中,从服务器通常被设置为只读模式,这样可以避免从服务器的数据被误修改。但是从服务器仍然可以接受CONFIG等指令,所以还是不应该将从服务器直接暴露到不安全的网络环境中。如果必须如此,那可以考虑给重要指令进行重命名,来避免命令被外人误执行。
从服务器会向主服务器发出SYNC指令,当主服务器接到此命令后,就会调用BGSAVE指令来创建一个子进程专门进行数据持久化工作,也就是将主服务器的数据写入RDB文件中。在数据持久化期间,主服务器将执行的写指令都缓存在内存中。
在BGSAVE指令执行完成后,主服务器会将持久化好的RDB文件发送给从服务器,从服务器接到此文件后会将其存储到磁盘上,然后再将其读取到内存中。这个动作完成后,主服务器会将这段时间缓存的写指令再以redis协议的格式发送给从服务器。
另外,要说的一点是,即使有多个从服务器同时发来SYNC指令,主服务器也只会执行一次BGSAVE,然后把持久化好的RDB文件发给多个下游。在redis2.8版本之前,如果从服务器与主服务器因某些原因断开连接的话,都会进行一次主从之间的全量的数据同步;而在2.8版本之后,redis支持了效率更高的增量同步策略,这大大降低了连接断开的恢复成本。
主服务器会在内存中维护一个缓冲区,缓冲区中存储着将要发给从服务器的内容。从服务器在与主服务器出现网络瞬断之后,从服务器会尝试再次与主服务器连接,一旦连接成功,从服务器就会把“希望同步的主服务器ID”和“希望请求的数据的偏移位置(replication offset)”发送出去。主服务器接收到这样的同步请求后,首先会验证主服务器ID是否和自己的ID匹配,其次会检查“请求的偏移位置”是否存在于自己的缓冲区中,如果两者都满足的话,主服务器就会向从服务器发送增量内容。
增量同步功能,需要服务器端支持全新的PSYNC指令。这个指令,只有在redis-2.8之后才具有。
事务处理
事务是指“一个完整的动作,要么全部执行,要么什么也没有做”。Redis的事物处理由4个基础指令组成:
1.MULTI用来组装一个事务;
2.EXEC用来执行一个事务;
3.DISCARD用来取消一个事务;
4.WATCH用来监视一些key,一旦这些key在事务执行之前被改变,则取消事务的执行。
Redis的漏洞
未授权漏洞
原理
Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。
危害
1、攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall来清空所有数据;
2、攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件;
3、最严重的情况,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器
防护
- 绑定IP的方式来进行控制。
在redis.conf文件找到如下配置
# If you want you can bind a single interface, if the bind option is not
# specified all the interfaces will listen for incoming connections.
#
# bind 127.0.0.1
把 #bind 127.0.0.1前面的注释#号去掉,然后把127.0.0.1改成允许访问redis服务器的ip地址,表示只允许该ip进行访问。这种情况下,在启动redis服务器的时候不能再用:redis-server,改为:redis-server path/redis.conf 即在启动的时候指定需要加载的配置文件,其中path/是上面修改的redis配置文件所在目录。
2.设置密码,以提供远程登陆
打开redis.conf配置文件,找到requirepass,然后修改如下:
requirepass yourpassword
yourpassword就是redis验证密码,设置密码以后发现可以登陆,但是无法执行命令了。
命令如下:
redis-cli -h yourIp -p yourPort//启动redis客户端,并连接服务器
keys * //输出服务器中的所有key
报错如下
(error) ERR operation not permitted
这时候你可以用授权命令进行授权,就不报错了
命令如下:
auth youpassword
以上是关于redis学习杂记的主要内容,如果未能解决你的问题,请参考以下文章