美文网首页
什么是Redis

什么是Redis

作者: 飞向天王星星 | 来源:发表于2022-07-09 22:38 被阅读0次

    底层数据结构:注意embstr——44个字节、quicklist——linklist+ziplist、skiplist——多级索引(指针)

    最终所有底层类型都封装成redisobject,然后映射到基本数据类型string/list/set/zset/hash

    10、redis 过期键的删除策略?

    (1)定时删除:在设置键的过期时间的同时,创建一个定时器 timer). 让定时 器在键的过期时

    间来临时,立即执行对键的删除操作。

    (2)惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得 的键是否过

    期,如果过期的话,就删除该键;如果没有过期,就返回该键。 (3)定期删除:每隔一段时间

    程序就对数据库进行一次检查,删除里面的过期 键。至于要删除多少过期键,以及要检查多

    少个数据库,则由算法决定。

    8、Redis 的持久化机制是什么?各自的优缺点?

    Redis 提供两种持久化机制 RDB 和 AOF 机制:

    13、Redis 的同步机制了解么?

    Redis 可以使用主从同步,从从同步。第一次同步时,主节点做一次 bgsave,并同时将后续

    修改操作记录到内存 buffer,待完成后将 rdb 文件全 量同步到复制节点,复制节点接受完成

    后将 rdb 镜像加载到内存。加载完成 后,再通知主节点将期间修改的操作记录同步到复制节

    点进行重放就完成了同步过程。

    14、Pipeline 有什么好处,为什么要用 pipeline?

    可以将多次 IO 往返的时间缩减为一次,前提是 pipeline 执行的指令之 间没有因果相关性。

    使用 redis-benchmark 进行压测的时候可以发现影响 redis 的 QPS 峰值的一个重要因素是

    pipeline 批次指令的数目。

    20、说说 Redis 哈希槽的概念?

    Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群 有 16384 个哈希

    槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置 哪个槽,集群的每个节点负责

    一部分 hash 槽

    37、假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的

    已知的前缀开头的,如果将 它们全部找出来?

    使用 keys 指令可以扫出指定模式的 key 列表。

    对方接着追问:如果这个 redis 正在给线上的业务提供服务,那使用 keys 指 令会有什么问

    题?

    203

    这个时候你要回答 redis 关键的一个特性:redis 的单线程的。keys 指令会 导致线程阻塞一

    段时间,线上服务会停顿,直到指令执行完毕,服务才能恢 复。这个时候可以使用 scan 指

    令,scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户

    端做一次去重就可以了,但是整 体所花费的时间会比直接用 keys 指令长。

    38、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?

    如果大量的 key 过期时间设置的过于集中,到过期的那个时间点,redis 可能会出现短暂的卡

    顿现象。一般需要在时间上加一个随机值,使得过期时间 分散一些

    如果能采用多线程,使得网络处理的请求并发进行,就可以大大的提升性能。多线程除了可以减少由于网络 I/O 等待造成的影响,还可以充分利用 CPU 的多核优势。

    所以,Redis 6.0采用多个IO线程来处理网络请求,网络请求的解析可以由其他线程完成,然后把解析后的请求交由主线程进行实际的内存读写。提升网络请求处理的并行度,进而提升整体性能。

    但是,Redis 的多 IO 线程只是用来处理网络请求的,对于读写命令,Redis 仍然使用单线程来处理。

    最牛逼的IO文章:

    https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg%3D%3D&idx=1&mid=2665525639&scene=21&sn=d0881894cfeca626c4e6b0953a32810b#wechat_redirect

    多路复用(multiplexing)是一个操作系统内核中的概念,并不是一种实现效果。对应linux操作系统,可以简单的认为,只有使用到了select、poll和epoll三个系统调用(system call)的程序才能称为多路复用器。

    阻塞IO和非阻塞IO的区别在于第一步(网卡->内核缓冲区,是否就绪),发起IO请求的进程是否会被阻塞,如果阻塞直到IO操作完成才返回那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。

    同步IO和异步IO的区别就在于第二步(内核缓冲区->用户缓冲区),实际的IO读写(内核态与用户态的数据拷贝)是否需要进程参与,如果需要进程参与则是同步IO,如果不需要进程参与就是异步IO。

    例子:排队买奶茶。排队等啥事都干不了(同步阻塞)、排队等的同时打打电话玩玩游戏时不时轮询等待着奶茶做完(同步非阻塞)、扫码下单后通过号码查询或者等服务员通知,中间什么事情都干不了(异步阻塞,大家都可以扫同一个码或等同一个服务员负责监听通知?)、扫码下单后通过号码查询等待完成或者等服务员通知,中间可以打打电话玩玩游戏(异步非阻塞)

    自己关于NIO的见解:

    NIO为什么是非阻塞的?因为NIO Reactor的线程不会阻塞,一直在处理各种事件,4种事件:客户端连接事件,连接就绪事件,读事件,写事件。而且它是同步的,因为需要NIO的线程自己去将数据从内核态拷贝到用户态,也需要将数据从用户态拷贝到内核态。

    IO多路复用和NIO是要配合一起使用才有实际意义。因此,在使用IO多路复用之前,请总是先把fd设为 O_NONBLOCK 。

    误解:❌ IO多路复用和NIO一起减少了IO。实际上,IO本身(网络数据的收发)无论用不用IO多路复用和NIO,都没有变化。请求的数据该是多少还是多少;网络上该传输多少数据还是多少数据。IO多路复用和NIO一起仅仅是解决了调度的问题,避免CPU在这个过程中的浪费,使系统的瓶颈更容易触达到网络带宽,而非CPU或者内存。要提高IO吞吐,还是提高硬件的容量(例如,用支持更大带宽的网线、网卡和交换机)和依靠并发传输(例如HDFS的数据多副本并发传输)。

    网络服务为了同时响应多个并发的网络请求,必须实现为多线程的。每个线程处理一个网络请求。线程数随着并发连接数线性增长。这的确能奏效。实际上2000年之前很多网络服务器就是这么实现的。但这带来两个问题:

    线程越多,Context Switch就越多,而Context Switch是一个比较重的操作,会无谓浪费大量的CPU。

    每个线程会占用一定的内存作为线程的栈。比如有1000个线程同时运行,每个占用1MB内存,就占用了1个G的内存。

    也许现在看来1GB内存不算什么,现在服务器上百G内存的配置现在司空见惯了。但是倒退20年,1G内存是很金贵的。并且,尽管现在通过使用大内存,可以轻易实现并发1万甚至10万的连接。但是水涨船高,如果是要单机撑1千万的连接呢?

    问题的关键在于,当调用 read 接受网络请求时,有数据到了就用,没数据到时,实际上是可以干别的。使用大量线程,仅仅是因为Block发生,没有其他办法。

    当然你可能会说,是不是可以弄个线程池呢?这样既能并发的处理请求,又不会产生大量线程。但这样会限制最大并发的连接数。比如你弄4个线程,那么最大4个线程都Block了就没法响应更多请求了。

    相关文章

      网友评论

          本文标题:什么是Redis

          本文链接:https://www.haomeiwen.com/subject/opjjbrtx.html