Redis有哪些数据结构?html
字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。node
若是你是Redis中高级用户,还须要加上下面几种数据结构HyperLogLog、Geo、Pub/Sub。面试
若是你说还玩过Redis Module,像BloomFilter,RedisSearch,Redis-ML,面试官得眼睛就开始发亮了。redis
假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,若是将它们所有找出来?数据库
使用keys指令能够扫出指定模式的key列表。可是redis的单线程的,keys指令会致使线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。缓存
这个时候可使用scan指令,scan指令能够无阻塞的提取出指定模式的key列表,可是会有必定的重复几率,在客户端作一次去重就能够了,可是总体所花费的时间会比直接用keys指令长。服务器
使用Redis作队列:网络
异步队列:数据结构
通常使用list结构做为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。架构
list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。
1:N的消息队列:
使用pub/sub主题订阅者模式实现,但在消费者下线的状况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。
延时队列:
使用sortedset,拿时间戳做为score,消息内容做为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒以前的数据轮询进行处理。
持久化:
bgsave作镜像全量持久化,aof作增量持久化。
由于bgsave会耗费较长时间,不够实时,在停机的时候会致使大量丢失数据,因此须要aof来配合使用。在redis实例重启时,会使用bgsave持久化文件从新构建内存,再使用aof重放近期的操做指令来实现完整恢复重启以前的状态。
若是忽然机器掉电会怎样?
取决于aof日志sync属性的配置,若是不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。可是在高性能的要求下每次都sync是不现实的,通常都使用定时sync,好比1s1次,这个时候最多就会丢失1s的数据。
bgsave的原理是什么?
fork和cow。fork是指redis经过建立子进程来进行bgsave操做,cow指的是copy on write,子进程建立后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。
1.redis调用fork,如今有了子进程和父进程。
2. 父进程继续处理client请求,子进程负责将内存内容写入到临时文件。因为os的写时复制机制(copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时os会为父进程要修改的页面建立副本,而不是写共享的页面。因此子进程的地址空间内的数 据是fork时刻整个数据库的一个快照。
3.当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,而后子进程退出。
aof 的方式也同时带来了另外一个问题。持久化文件会变的愈来愈大。例如咱们调用incr test命令100次,文件中必须保存所有的100条命令,其实有99条都是多余的。由于要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis将使用与快照相似的方式将内存中的数据 以命令的方式保存到临时文件中,最后替换原来的文件。具体过程以下
1. redis调用fork ,如今有父子两个进程
2. 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
3.父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证若是子进程重写失败的话并不会出问题。
4.当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。而后父进程把缓存的写命令也写入到临时文件。
5.如今父进程可使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。
须要注意到是重写aof文件的操做,并无读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点相似。
Redis的同步机制?
Redis可使用主从同步,从从同步。第一次同步时,主节点作一次bgsave,并同时将后续修改操做记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操做记录同步到复制节点进行重放就完成了同步过程。
https://mp.weixin.qq.com/s/507jyNbL4xCkxyW6Xk15Xg
当用户往Master端写入数据时,经过Redis Sync机制将数据文件发送至Slave,Slave也会执行相同的操做确保数据一致;
一、同一个Master能够拥有多个Slaves。
二、Master下的Slave还能够接受同一架构中其它slave的连接与同步请求,实现数据的级联复制,即Master->Slave->Slave模式;
三、Master以非阻塞的方式同步数据至slave,这将意味着Master会继续处理一个或多个slave的读写请求;
四、Slave端同步数据也能够修改成非阻塞是的方式,当slave在执行新的同步时,它仍能够用旧的数据信息来提供查询;不然,当slave与master失去联系时,slave会返回一个错误给客户端;
五、主从复制具备可扩展性,即多个slave专门提供只读查询与数据的冗余,Master端专门提供写操做;
六、经过配置禁用Master数据持久化机制,将其数据持久化操做交给Slaves完成,避免在Master中要有独立的进程来完成此操做。
当启动一个Slave进程后,它会向Master发送一个SYNC Command,请求同步链接。
不管是第一次链接仍是从新链接,Master都会启动一个后台进程,将数据快照保存到数据文件中,同时Master会记录全部修改数据的命令并缓存在数据文件中。
后台进程完成缓存操做后,Master就发送数据文件给Slave,Slave端将数据文件保存到硬盘上,而后将其在加载到内存中,接着Master就会全部修改数据的操做,将其发送给Slave端。
若Slave出现故障致使宕机,恢复正常后会自动从新链接,Master收到Slave的链接后,将其完整的数据文件发送给Slave,若是Mater同时收到多个Slave发来的同步请求,Master只会在后台启动一个进程保存数据文件,而后将其发送给全部的Slave,确保Slave正常。
http://blog.51cto.com/cfwlxf/1433637
redis事物的了解CAS
在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是咱们实现事务的基石。redis事务的实现特征:
1). 在事务中的全部命令都将会被串行化的顺序执行,事务执行期间,Redis不会再为其它客户端的请求提供任何服务,从而保证了事物中的全部命令被原子的执行。
2). 和关系型数据库中的事务相比,在Redis事务中若是有某一条命令执行失败,其后的命令仍然会被继续执行。
3). 咱们能够经过MULTI命令开启一个事务,有关系型数据库开发经验的人能够将其理解为"BEGIN TRANSACTION"语句。在该语句以后执行的命令都将被视为事务以内的操做,最后咱们能够经过执行EXEC/DISCARD命令来提交/回滚该事务内的全部操做。这两
个Redis命令可被视为等同于关系型数据库中的COMMIT/ROLLBACK语句。
4). 在事务开启以前,若是客户端与服务器之间出现通信故障并致使网络断开,其后全部待执行的语句都将不会被服务器执行。然而若是网络中断事件是发生在客户端执行EXEC命令以后,那么该事务中的全部命令都会被服务器执行。
5). 当使用Append-Only模式时,Redis会经过调用系统函数write将该事务内的全部写操做在本次调用中所有写入磁盘。然而若是在写入的过程当中出现系统崩溃,如电源故障致使的宕机,那么此时也许只有部分数据被写入到磁盘,而另一部分数据却已经丢失。
Redis服务器会在从新启动时执行一系列必要的一致性检测,一旦发现相似问题,就会当即退出并给出相应的错误提示。此时,咱们就要充分利用Redis工具包中提供的redis-check-aof工具,该工具能够帮助咱们定位到数据不一致的错误,并将已经写入的部
分数据进行回滚。修复以后咱们就能够再次从新启动Redis服务器了。
WATCH命令和基于CAS的乐观锁:
在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能。假设咱们经过WATCH命令在事务执行以前监控了多个Keys,假若在WATCH以后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Null multi-bulk应答以通知调用者事务
redis持久化的几种方式
一、快照(snapshots)
缺省状况状况下,Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb。你能够配置Redis的持久化策略,例如数据集中每N秒钟有超过M次更新,就将数据写入磁盘;或者你能够手工调用命令SAVE或BGSAVE。
工做原理
. Redis forks.
. 子进程开始将数据写到临时RDB文件中。
. 当子进程完成写RDB文件,用新文件替换老文件。
. 这种方式可使Redis使用copy-on-write技术。
二、AOF
快照模式并不十分jian壮,当系统中止,或者无心中Redis被kill掉,最后写入Redis的数据就会丢失。这对某些应用也许不是大问题,但对于要求高可靠性的应用来讲,
Redis就不是一个合适的选择。
Append-only文件模式是另外一种选择。
你能够在配置文件中打开AOF模式
三、虚拟内存方式
当你的key很小而value很大时,使用VM的效果会比较好.由于这样节约的内存比较大.
当你的key不小时,能够考虑使用一些很是方法将很大的key变成很大的value,好比你能够考虑将key,value组合成一个新的value.
vm-max-threads这个参数,能够设置访问swap文件的线程数,设置最好不要超过机器的核数,若是设置为0,那么全部对swap文件的操做都是串行的.可能会形成比较长时间的延迟,可是对数据完整性有很好的保证.
本身测试的时候发现用虚拟内存性能也不错。若是数据量很大,能够考虑分布式或者其余数据库
https://www.cnblogs.com/Survivalist/p/8119891.html
redis 4.0
Redis 4.0 之前存在的问题:1,节点重启后须要全力拉取数据; 2,发生主从切换后,新的从节点都须要从新与主节点进去全量的数据同步 3,aof数据加载很慢;
Redis 4.0 引入了两项新的技术来解决了上述问题,Psync2,混合rdb、aof 文件。
1, Psync 2 : 解决了从库重启以及发生主从切换以后的全量同步问题。
以前的版本中,从库重启须要全量同步的缘由是从库没有将主节点的runId持久化(runId 是和 节点的nodeId 不一样?),因此从节点重启后由于没有了这个runId 因此须要全量同步。新的版本中在RDB文件保存了这个runid,解决了重启节点须要全量同步的问题。
Redis 4.0 容许多级slave 的存在,便可以有这样的形式 A(主) → B (从) → C(从) → D (从) (Replication version 2); 当发生主从切换后,新的主节点能够判断从节点是否知足部分同步的条件: 以前就是重新主节点同步的或者以前和新主节点同步的是同一个master, 其余的条件好比backlog 和offset 的位置和以前的版本同样。
2, Mixed-rdb & aof: 解决aof文件加载慢问题。
aof相比rdb文件来讲恢复数据的速度要慢不少。4.0 之后的aof重写再也不是像以前同样将数据以aof 的格式写入到文件中, 而是先写成rdb 的格式 (应该是先作一份全量的rdb,而后存储进文件中去,这样就必定快不少?这个和重写aof 的数据量应该差很少才是)。
http://blog.csdn.net/agangdi/article/details/21567199