1.什么是redis?python
Redis 是一个基于内存的高性能key-value数据库。 web
2.Reids的特色 redis
Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库通通加载在内存当中进行操做,按期经过异步操做把数据库数据flush到硬盘上进行保存。算法
由于是纯内存操做,Redis的性能很是出色,每秒能够处理超过 10万次读写操做,是已知性能最快的Key-Value DB。数据库
Redis的出色之处不只仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像 memcached只能保存1MB的数据,所以Redis能够用来实现不少有用的功能。后端
比方说用他的List来作FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set能够作高性能的tag系统等等。另外Redis也能够对存入的Key-Value设置expire时间,所以也能够被看成一 个功能增强版的memcached来用。缓存
Redis的主要缺点是数据库容量受到物理内存的限制,不能用做海量数据的高性能读写,所以Redis适合的场景主要局限在较小数据量的高性能操做和运算上。服务器
3.使用redis有哪些好处? 网络
4.redis相比memcached有哪些优点? session
5.Memcache与Redis的区别都有哪些?
6.redis常见性能问题和解决方案:
7. mySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据
相关知识:redis 内存数据集大小上升到必定大小的时候,就会施行数据淘汰策略(回收策略)。
redis 提供 6种数据淘汰策略:
8.请用Redis和任意语言实现一段恶意登陆保护的代码,限制1小时内每用户Id最多只能登陆5次。具体登陆函数或功能用空函数便可,不用详细写出。
用列表实现:列表中每一个元素表明登录时间,只要最后的第5次登录时间和如今时间差不超过1小时就禁止登录.用Python写的代码以下:
#!/usr/bin/env python3 import redis import sys import time r = redis.StrictRedis(host=’127.0.0.1′, port=6379, db=0) try: id = sys.argv[1] except: print(‘input argument error’) sys.exit(0) if r.llen(id) >= 5 and time.time() – float(r.lindex(id, 4)) <= 3600: print(“you are forbidden logining”) else: print(‘you are allowed to login’) r.lpush(id, time.time()) # login_func()
9.为何redis须要把全部数据放到内存中?
Redis为了达到最快的读写速度将数据都读到内存中,并经过异步的方式将数据写入磁盘。因此redis具备快速和数据持久化的特征。若是不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。在内存愈来愈便宜的今天,redis将会愈来愈受欢迎。
若是设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
10.Redis是单进程单线程的
redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销
11.redis的并发竞争问题如何解决?
Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis自己没有锁的概念,Redis对于多个客户端链接并不存在竞争,可是在Jedis客户端对Redis进行并发访问时会发生链接超时、数据转换错误、阻塞、客户端关闭链接等问题,这些问题均是因为客户端链接混乱形成。
对此有2种解决方法:
1.客户端角度,为保证每一个客户端间正常有序与Redis进行通讯,对链接进行池化,同时对客户端读写Redis操做采用内部锁synchronized。
2.服务器角度,利用setnx实现锁。
注:对于第一种,须要应用程序本身处理资源的同步,可使用的方法比较通俗,可使用synchronized也可使用lock;第二种须要用到Redis的setnx命令,可是须要注意一些问题。
12.redis事物的了解CAS(check-and-set 操做实现乐观锁 )?
和众多其它数据库同样,Redis做为NoSQL数据库也一样提供了事务机制。在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是咱们实现事务的基石。
相信对有关系型数据库开发经验的开发者而言这一律念并不陌生,即使如此,咱们仍是会简要的列出Redis中事务的实现特征:
Redis服务器会在从新启动时执行一系列必要的一致性检测,一旦发现相似问题,就会当即退出并给出相应的错误提示。
此时,咱们就要充分利用Redis工具包中提供的redis-check-aof工具,该工具能够帮助咱们定位到数据不一致的错误,并将已经写入的部分数据进行回滚。修复以后咱们就能够再次从新启动Redis服务器了。
13.WATCH命令和基于CAS的乐观锁:
在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能。假设咱们经过WATCH命令在事务执行以前监控了多个Keys,假若在WATCH以后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Null multi-bulk应答以通知调用者事务
执行失败。例如,咱们再次假设Redis中并未提供incr命令来完成键值的原子性递增,若是要实现该功能,咱们只能自行编写相应的代码。其伪码以下:
val = GET mykey val = val + 1 SET mykey $val
以上代码只有在单链接的状况下才能够保证执行结果是正确的,由于若是在同一时刻有多个客户端在同时执行该段代码,那么就会出现多线程程序中常常出现的一种错误场景--竞态争用(race condition)。
好比,客户端A和B都在同一时刻读取了mykey的原有值,假设该值为10,此后两个客户端又均将该值加一后set回Redis服务器,这样就会致使mykey的结果为11,而不是咱们认为的12。为了解决相似的问题,咱们须要借助WATCH命令的帮助,见以下代码:
WATCH mykey val = GET mykey val = val + 1 MULTI SET mykey $val EXEC
和此前代码不一样的是,新代码在获取mykey的值以前先经过WATCH命令监控了该键,此后又将set命令包围在事务中,这样就能够有效的保证每一个链接在执行EXEC以前,若是当前链接获取的mykey的值被其它链接的客户端修改,那么当前链接的EXEC命令将执行失败。这样调用者在判断返回值后就能够获悉val是否被从新设置成功。
14.redis持久化的几种方式
一、快照(snapshots)
缺省状况状况下,Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb。你能够配置Redis的持久化策略,例如数据集中每N秒钟有超过M次更新,就将数据写入磁盘;或者你能够手工调用命令SAVE或BGSAVE。
工做原理
二、AOF
快照模式并不十分健壮,当系统中止,或者无心中Redis被kill掉,最后写入Redis的数据就会丢失。
这对某些应用也许不是大问题,但对于要求高可靠性的应用来讲,Redis就不是一个合适的选择。Append-only文件模式是另外一种选择。你能够在配置文件中打开AOF模式
三、虚拟内存方式
当你的key很小而value很大时,使用VM的效果会比较好.由于这样节约的内存比较大.
当你的key不小时,能够考虑使用一些很是方法将很大的key变成很大的value,好比你能够考虑将key,value组合成一个新的value.
vm-max-threads这个参数,能够设置访问swap文件的线程数,设置最好不要超过机器的核数,若是设置为0,那么全部对swap文件的操做都是串行的.可能会形成比较长时间的延迟,可是对数据完整性有很好的保证.
本身测试的时候发现用虚拟内存性能也不错。若是数据量很大,能够考虑分布式或者其余数据库。
15.redis的缓存失效策略和主键失效机制
做为缓存系统都要按期清理无效数据,就须要一个主键失效和淘汰策略.
在Redis当中,有生存期的key被称为volatile。在建立缓存时,要为给定的key设置生存期,当key过时的时候(生存期为0),它可能会被删除。
一、影响生存时间的一些操做
生存时间能够经过使用 DEL 命令来删除整个 key 来移除,或者被 SET 和 GETSET 命令覆盖原来的数据,也就是说,修改key对应的value和使用另外相同的key和value来覆盖之后,当前数据的生存时间不一样。
好比说,对一个 key 执行INCR命令,对一个列表进行LPUSH命令,或者对一个哈希表执行HSET命令,这类操做都不会修改 key 自己的生存时间。另外一方面,若是使用RENAME对一个 key 进行更名,那么更名后的 key的生存时间和更名前同样。
RENAME命令的另外一种多是,尝试将一个带生存时间的 key 更名成另外一个带生存时间的 another_key ,这时旧的 another_key (以及它的生存时间)会被删除,而后旧的 key 会更名为 another_key ,所以,新的 another_key 的生存时间也和本来的 key 同样。使用PERSIST命令能够在不删除 key 的状况下,移除 key 的生存时间,让 key 从新成为一个persistent key 。
二、如何更新生存时间
能够对一个已经带有生存时间的 key 执行EXPIRE命令,新指定的生存时间会取代旧的生存时间。过时时间的精度已经被控制在1ms以内,主键失效的时间复杂度是O(1),EXPIRE和TTL命令搭配使用,TTL能够查看key的当前生存时间。设置成功返回 1;当 key 不存在或者不能为 key 设置生存时间时,返回 0 。
最大缓存配置:
在 redis 中,容许用户设置最大使用内存大小,server.maxmemory默认为0,没有指定最大缓存,若是有新的数据添加,超过最大内存,则会使redis崩溃,因此必定要设置。redis 内存数据集大小上升到必定大小的时候,就会实行数据淘汰策略。
redis 提供 6种数据淘汰策略:
注意这里的6种机制,volatile和allkeys规定了是对已设置过时时间的数据集淘汰数据仍是从所有数据集淘汰数据,后面的lru、ttl以及random是三种不一样的淘汰策略,再加上一种no-enviction永不回收的策略。
使用策略规则:
三种数据淘汰策略:
ttl和random比较容易理解,实现也会比较简单。主要是Lru最近最少使用淘汰策略,设计上会对key 按失效时间排序,而后取最早失效的key进行淘汰
16.redis 最适合的场景
Redis最适合全部数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差异,那么可能你们就会有疑问,彷佛Redis更像一个增强版的Memcached,那么什么时候使用Memcached,什么时候使用Redis呢?
若是简单地比较Redis与Memcached的区别,大多数都会获得如下观点:
一、会话缓存(Session Cache)
最经常使用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其余存储(如Memcached)的优点在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,若是用户的购物车信息所有丢失,大部分人都会不高兴的,如今,他们还会这样吗?
幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。
二、全页缓存(FPC)
除基本的会话token以外,Redis还提供很简便的FPC平台。回到一致性问题,即便重启了Redis实例,由于有磁盘的持久化,用户也不会看到页面加载速度的降低,这是一个极大改进,相似PHP本地FPC。
再次以Magento为例,Magento提供一个插件来使用Redis做为全页缓存后端。
此外,对WordPress的用户来讲,Pantheon有一个很是好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。
三、队列
Reids在内存存储引擎领域的一大优势是提供 list 和 set 操做,这使得Redis能做为一个很好的消息队列平台来使用。Redis做为队列使用的操做,就相似于本地程序语言(如Python)对 list 的 push/pop 操做。
若是你快速的在Google中搜索“Redis queues”,你立刻就能找到大量的开源项目,这些项目的目的就是利用Redis建立很是好的后端工具,以知足各类队列需求。例如,Celery有一个后台就是使用Redis做为broker,你能够从这里去查看。
四、排行榜/计数器
Redis在内存中对数字进行递增或递减的操做实现的很是好。集合(Set)和有序集合(Sorted Set)也使得咱们在执行这些操做的时候变的很是简单,Redis只是正好提供了这两种数据结构。
因此,咱们要从排序集合中获取到排名最靠前的10个用户–咱们称之为“user_scores”,咱们只须要像下面同样执行便可:
固然,这是假定你是根据你用户的分数作递增的排序。若是你想返回用户及用户的分数,你须要这样执行:
ZRANGE user_scores 0 10 WITHSCORES
Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你能够在这里看到。
五、发布/订阅
最后(但确定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实很是多。我已看见人们在社交网络链接中使用,还可做为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来创建聊天系统!(不,这是真的,你能够去核实)。
Redis提供的全部特性中,我感受这个是喜欢的人最少的一个,虽然它为用户提供若是此多功能。
1七、Redis集群方案什么状况下会致使整个集群不可用?
有A,B,C三个节点的集群,在没有复制模型的状况下,若是节点B失败了,那么整个集群就会觉得缺乏5501-11000这个范围的槽而不可用。
1八、Redis支持的Java客户端都有哪些?官方推荐用哪一个?
Redisson、Jedis、lettuce等等,官方推荐使用Redisson。
1九、Redis和Redisson有什么关系?
Redisson是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象 (Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。
20、Jedis与Redisson对比有什么优缺点?
Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;
Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操做,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者可以将精力更集中地放在处理业务逻辑上。
2一、Redis如何设置密码及验证密码?
设置密码:config set requirepass 123456 受权密码:auth 123456
2二、说说Redis哈希槽的概念?
Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,每一个key经过CRC16校验后对16384取模来决定放置哪一个槽,集群的每一个节点负责一部分hash槽。
2三、Redis集群的主从复制模型是怎样的?
为了使在部分节点失败或者大部分节点没法通讯的状况下集群仍然可用,因此集群使用了主从复制模型,每一个节点都会有N-1个复制品.
2四、Redis集群会有写操做丢失吗?为何?
Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操做。
2五、Redis集群之间是如何复制的?
异步复制
2六、Redis集群最大节点个数是多少?
16384个。
2七、Redis集群如何选择数据库?
Redis集群目前没法作数据库选择,默认在0数据库。
2八、怎么测试Redis的连通性?
ping
2九、Redis中的管道有什么用?
一次请求/响应服务器能实现处理新的请求即便旧的请求还未被响应。这样就能够将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。
这就是管道(pipelining),是一种几十年来普遍使用的技术。例如许多POP3协议已经实现支持这个功能,大大加快了从服务器下载新邮件的过程。
30、怎么理解Redis事务?
事务是一个单独的隔离操做:事务中的全部命令都会序列化、按顺序地执行。事务在执行的过程当中,不会被其余客户端发送来的命令请求所打断。
事务是一个原子操做:事务中的命令要么所有被执行,要么所有都不执行。
3一、Redis事务相关的命令有哪几个?
MULTI、EXEC、DISCARD、WATCH
3二、Redis key的过时时间和永久有效分别怎么设置?
EXPIRE和PERSIST命令。
3三、Redis如何作内存优化?
尽量使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存很是小,因此你应该尽量的将你的数据模型抽象到一个散列表里面。
好比你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的全部信息存储到一张散列表里面。
3四、Redis回收进程如何工做的?
一个客户端运行了新的命令,添加了新的数据。
Redi检查内存使用状况,若是大于maxmemory的限制, 则根据设定好的策略进行回收。
一个新的命令被执行,等等。
因此咱们不断地穿越内存限制的边界,经过不断达到边界而后不断地回收回到边界如下。
若是一个命令的结果致使大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。
3五、Redis集群方案应该怎么作?都有哪些方案?
1.codis。
目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在 节点数量改变状况下,旧节点数据可恢复到新hash节点。
2.redis cluster3.0自带的集群,特色在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。具体看官方文档介绍。
3.在业务代码层实现,起几个毫无关联的redis实例,在代码层,对key 进行hash计算,而后去对应的redis实例操做数据。 这种方式对hash层代码要求比较高,考虑部分包括,节点失效后的替代算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。