请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

在前几章积累的一些问题,希望老师能答疑解惑,非常感谢!!!

老师您好!您的视频真的每一秒都是干货啊!
从4-1看过来,积累了一些问题,还希望老师可以指点解答

  1. 关于Redis我大概的想象是它对外有一个线程,来接受外部的一些请求事件,而这个线程通过IO复用来在内部创建新的线程对内部的数据进行操作,不知道是不是这样呢?
  2. 如果上面这一点理解的没有问题的话,在KEY pattern那里,老师说“键的数量过大会使服务卡顿”,这个是为什么呢?是因为默认用主线程来做的吗查询吗?既然对内通过IO复用创建了新的线程操作数据,是不是调用KEY时也会创建一个线程去负责查询(和其他线程并发),此时应该是不应该发生卡顿的呀
  3. 实现分布式锁部分,通过SETNX+EXPIRE或融合二者SET都可以实现在一定时间后使key过期,如果此时一个进程成功设置key,然后设置了过期时间,但执行独占资源代码块时的时间远远超过过期时间,此时另一个线程就可以设置key,进入独占资源代码块,此时会不会发生冲突呢?
  4. 异步队列部分,老师说“缺点是LPOP没有等待队列里有值就直接消费”,替换方法就是sleep,这个不是很理解,LPOP方法在没有消费的时候会返回nil而不是报错,因此不存在程序异常的问题,那么线程是会不停的调用LPOP吗?但是调用sleep也是让线程阻塞一段时间,两种方法对于线程来说都是没有做任何事也不报错,那么为什么说LPOP是有缺点的,可以用sleep替换呢?
  5. 持久化部分,想请教一下老师我理解的对不对:
    1.由于Copy-on-Write,主进程fork出子进程后,他们是共享一片物理地址中的内容的
    2.此时子进程负责去在这片空间中拿东西拷贝,而父进程(也是主进程)会继续去处理外面来的请求
    3.如果这时候父进程接到了一个写的请求,同样由于Copy-on-Write,会先创建一个副本(另外的一片物理空间中),在这个副本上进行操作(或记录要操作的步骤?)
    4.这时候子进程已经拷贝完了,父进程会拿着刚才副本中的操作到刚才他们共享的那个地方去覆盖原来的数据(或按照记录的操作进行操作?)
    5.整个过程中父进程要读哪里,写哪里是由Copy-on-Write维护的读请求使用的指针控制的
  6. 还有个小问题,想请教一下老师:**Redis用的最多的地方是在数据库前面做一个缓存吗?就像内存前面的cache一样?那么可不可以认为课程里面您讲的“写入磁盘”,其实就是写入到数据库呢?**此外,如果在服务器中用到Redis,是不是对服务器硬件(处理器,内存)的要求都很高呢?
    问题比较多,还请麻烦老师您能抽空指点迷津!提前感谢您!!!
    非常感谢!!!

正在回答

2回答

同学好,感谢同学对课程的肯定:)下面是对每个问题的回答哈

  1. 不算是,redis是单线程来处理数据,所以都是同一个线程,只是使用了IO复用来解决IO阻塞的问题,.I/O多路复用本来就是用来解决对多个I/O监听时,一个I/O阻塞影响其他I/O的问题,跟多线程没关系。具体可以参考https://blog.csdn.net/diweikang/article/details/90346020

  2. 因为redis是单线程的,而数据量过大的话,必然会使得模糊查询性能降低,所以会造成单线程处理上的阻塞

  3. 肯定会造成冲突的,但是我们设置过期时间是经过压测的,通常是多于最长时间的1.5倍,所以会大概率杜绝这种问题的发生,而且同学不用担心key长时间不释放,毕竟只有发生极端异常的情况下,才会导致key不被清理,因此才有了过期时间的设定,通常情况下,执行完成之后,我们往往会在程序里及时将锁释放

  4. lpop因为不像java 里面的future get一样去等待有数据才返回,一调用不管有没有都会直接返回,这样的特性导致了它不能满足消息队列有消息才消费的需求,并且如果在外层写while的时候,就会不断调用lpop进而占用单线程的redis的执行,所以需要做适当的sleep

  5. COW是一种计算机程序设计领域的优化策略。其核心思想是,如果有多个调用者(callers)同时请求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。redis提供了bgrewriteaof命令对日志进行压缩。bgrewriteaof命令也会调用fork()函数,利用子进程中的数据状态转化成redis命令并保存到新的aof日志中,之后同步父进程中缓存的新写命令,最后用新日志文件替换旧日志文件.

  6. 很多场景确实如同学所说,并且因为redis支持了比较丰富的数据类型,所以应用场景比一般的缓存要多。也有使用redis来作为唯一数据源的应用,主要是应对读取比较频繁的场景,毕竟内存操作比数据库的文件操作性能要高,缓存对内存要求较高,但是对cpu其实和数据库差不多,不过高性能的程序必然意味着需要有高性能的CPU,这个主要是跟业务来,跟redis无关。

  7. RDB和AOF里面的指令都具有原子性。

    混合模式流程如下:

    当 rewrite 触发之后

    主进程 fork 出子进程, 对 aof 文件进行重写 , 会先做出一个临时的文件

    对这个文件进行 rdb 的方式 , 以及 fork时刻时的 日志

    完成之后 会 告知 主进程, 对增量的日志就进行追加 日志之后

    完成之后, 修改名称 覆盖 原来的aof 文件. 完成 过程。因此并非对RDB和AOF部分单独都fork出进程

1 回复 有任何疑惑可以回复我~
  • 提问者 慕少1113164 #1
    哇!非常非常感谢老师的耐心解答!!!
    回复 有任何疑惑可以回复我~ 2020-09-03 03:33:20
提问者 慕少1113164 2020-09-02 03:49:21

不好意思老师,刚才又有一个新的小问题(ಥ_ಥ) 

7.混合模式持久化时,主进程会对RDB部分和AOF部分分别fork出两个进程,一个通过管道读取快照时刻父进程对应物理空间的数据,一个通过管道读取父进程的增量数据吗?RDB,AOP,RDB+AOP都是具备原子性的吗?

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号