redis相关

1、redis是单线程的,为什么还这么快(除了内存)?

  1)完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,

      HashMap的优势就是查找和操作的时间复杂度都是O(1);

  2)数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

  3)采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗

    CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

  4)使用多路I/O复用模型,非阻塞IO:

         1.1什么是非阻塞IO:

                1) 一个服务器进程和一个客户端进程通信,服 务器端read(sockfd1,bud,bufsize),此时客户

                 端进程没有发送数据,那么read(阻塞调用)将阻塞直到客户端调用write(sockfd,but,size)发来数据.  

                 在一个客户和服务器通信时这没什么问题,当多个客户与服务器通信时,若服务器阻塞于其中一个客户sockfd1,当另一个       

                 客户的数据到达套接字sockfd2时,服务器不能处理,仍然阻塞在read(sockfd1,...)上;此时       

                 问题就出现了,不能及时处理另一个客户的服务

                 while ((n = read(fd_read, buf, SIZE)) > 0)            if ( write(fd_write, buf, SIZE) != n)  echo("write error")          2)IO多路转接技术的内容就是:线构造一张或多张描述符的表,然后调用一个函数,知道有表中的描述符准备好可以进行IO操作时,该函数才返回,在返回时告诉进程哪一个描述符已经准备好了,可以进行IO操作,对该描述符进行IO操作就不会阻塞.

                     

      

2、redis分布式锁的问题?

 SET my_key my_value NX PX milliseconds。

加锁代码满足我们可靠性里描述的三个条件:

首先,set()加入了NX参数,可以保证如果已有key存在,则函数不会调用成功,也就是只有一个客户端能持有锁,满足互斥性。    

其次,由于我们对锁设置了过期时间,即使锁的持有者后续发生崩溃而没有解锁,锁也会因为到了过期时间而自动解锁(即key被删除),不会发生死锁。

最后,因为我们将value赋值为requestId,代表加锁的客户端请求标识,那么在客户端在解锁的时候就可以进行校验是否是同一个客户端。

===================解读========

 SET my_key my_value NX PX milliseconds。

加锁:setNx 方法,如果key存在,则不会拿到锁。并且设置所得过期时间,不会发生死锁。

解锁:redis中key对应的value与之前设置的是否一致,防止解别人的锁;使用lua代码保证操作的原子性;

3、redis的五种数据类型,hash底层的数据结构是怎么样的?String在底层存储的是什么?

    1)五种数据类型:String、List、Set、Hash、ZSet

    2)Hash底层数据结构类型:

      Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口。

      也就是说,Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值;

      这样对数据的修改和存取都可以直接通过其内部Map的 Key(Redis里称内部Map的key为field),

      也就是通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,

      也不会带来序列化和并发修改控制的问题。

    3)redis的String类型底层为二进制数据,因为任何类型数据都可以表示成二进制,redis的字符串可以存储任何类型的数据;

4、redis的持久化策略?

   1)、快照(snapshots)

  当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。n秒内m个key被修改。

    快照模式并不十分健壮,当系统停止,或者无意中Redis被kill掉,最后写入Redis的数据就会丢失。

   2)、aof(append only file)appendonly yes

      ①appendfsync no 由操作系统决定时机,一般30s一次;

      ②appendfsync everysec每秒扫描一次,有改变就持久化

      ③appednfsync always每个操作持久化

5、redis内存不够的策略有哪些?lru有哪几种方法? LRU驱动事件(LRU eviction)

      volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

      volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

      volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

      allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

      allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

      no-enviction(驱逐):禁止驱逐数据

   使用策略规则:

1)、如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru

2)、如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkeys-random

6、redis如何找到近期的key?

    KEYS pattern 列出匹配的keys

    scan pattern 不会导致线程的阻塞,

    TTL key  当 key 不存在时,返回 -2;当 key 存在但没有设置剩余生存时间时,返回 -1;否则,以秒为单位,返回 key 的剩余生存时间

    

7、redis的集群结构有哪几种?哪个地方去记录了哪个hash槽的位置(cluster,管理集群的插件)?

   1)哨兵:高可用特性都会受到Master主节点内存的限制。

    哨兵的作用就是监控Redis系统的运行状况。它的功能包括以下两个。

    ①监控主数据库和从数据库是否正常运行。

    ②主数据库出现故障时自动将从数据库转换为主数据库。

   哨兵模式的优缺点

    优点:

     主从可以切换,故障可以转移,系统可用性更好。哨兵模式是主从模式的升级,系统更健壮,可用性更高。

    缺点:

      高可用特性都会受到Master主节点内存的限制,Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

   2)集群

      在redis官方给出的集群方案中,数据的分配是按照槽位来进行分配的,每一个数据的键被哈希函数映射到一个槽位,redis-3.0.0规定一共有16384个槽位,当然这个可以根据用户的喜好进行配置(slot-add)。当用户put或者是get一个数据的时候,首先会查找这个数据对应的槽位是多少,然后查找对应的节点,然后才把数据放入这个节点。这样就做到了把数据均匀的分配到集群中的每一个节点上,从而做到了每一个节点的负载均衡,充分发挥了集群的威力。

      当其中一个节点node1执行set a a 命令时,redis 先对 key 使用 crc16 算法算出一个结果,

      然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽(但一个hash槽会对应许多keys),redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。

      set的步骤如下所示:①node1实行set key value ②cluster对key进行算法计算,并对16384取余数,得到插槽位置,比如node2 ③在node2上 set key value;

      get的步骤如下①计算key值,得到槽值位于node2 ②跳转至node2 ③在node2上执行get key命令

      优点:使用哈希槽的好处就在于可以方便的添加或移除节点。

            当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;

            当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;在这一点上,我们以后新增或移除节点的时候不用先停掉所有的 redis 服务。

8、redis性能优化问题

(1)Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件;(Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照;AOF文件过大会影响Master重启的恢复速度)

(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...;这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

9、

redis.conf中设置:

端口号port:

后台启动daemonize:yes

主从启动:slaveof

10、缓存穿透是什么,你认为该如何解决这个问题?

    缓存穿透,是指查询一个数据库一定不存在的数据。

         缺点:假如有恶意攻击,就可以利用这个漏洞,对数据库造成压力,甚至压垮数据库。

         解决:缓存空值;

    缓存雪崩,是指在某一个时间段,缓存集中过期失效。

         缺点:对于数据库而言,就会产生周期性的压力波峰。

         解决:不同的分类设置不同的过期时间;

    缓存击穿,是指某一个非常热点的key瞬间失效,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

          缺点:主打的商品永不过期

11、Redis客户端

Redis Client

12、LPOP和BLPOP的区别

   LBPOP支持多个key,也就是说可以同时监听多个list,并按照key的

   LPOP 删除并返回删除值

13、Redis中的lua用过没,可以用来做什么,为什么可以这么用?

        注意一点 lua脚本是一个原子性的操作,只有当lua脚本执行完毕之后,redis的其他操作才能正常执行。

        可以用来分布式事务中解锁操作;加锁过程中setnx操作,保证key已经存在,那么函数不会调用成功;

        解锁呢,需要两步来实现:首先判断key对应的value与之前是否一致,然后一致解锁;用lua可以保证操作的原子性,防止解了别人的锁;

    

14、Redis的pipeline用来做什么?

pipeline就是把一组命令进行打包,然后一次性通过网络发送到Redis。同时将执行的结果批量的返回回来;节约发送的往返时间;

15、redis MemCached  CasSandra的区别

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2) redis的速度比memcached快很多

(3) redis可以持久化其数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值