• 樱花落花
    2019-09-02
    LRU算法最经典的我觉得还是MySQL的bufferpool的设计,里面按比例分为young和old区,能很好的解决预读问题和老师讲的“挖坟”问题;
     1
     15
  • 姜戈
    2019-08-30
    利用双向链表+哈希表, 支持所有操作时间复杂度都为O(1). https://github.com/djangogao/mqexercise.git
    实现了最基础LRU算法, 关于LRU的改进算法:LRU-K和 LRU 2Q,可参考此文章https://www.jianshu.com/p/c4e4d55706ff
    
     8
  • leslie
    2019-08-29
    一路跟着三位老师在同时学习相关知识:我想我大致明白了消息队列的特性以及真正适用的场景,周二许老师的课程中刚好提到了相关东西特意为了许老师。
        关系型数据库、非关系型数据库、消息队列其实都属于存储中间件,老师今天的话题如何利用缓存来减少磁盘IO其实就是涉及了三种存储中间件;其实老师今天的三种方法我的理解其实就是对应了三种存储中间件:三种存储中间件都和内存有关,如何合理使用缓存、内存、磁盘去做合适的事情才是关键;
    老师课程的算法:几门相关的课程同时在学时间还是偏紧,不过刘老师的操作系统、许老师的架构、以及老师的消息队列同时学习,倒是了解什么场景下用以及用哪种消息队列;至少跟着老师的消息队列我应当知道业务中的什么事情让它去承担并且使用什么策略,先用现成的吧;改进只能等第二遍学习时再去做了。
      一直跟着学习学到现在发现学好消息队列的前提:1)对业务的数据情况清楚2)对于当下使用的存储中间件情况非常清楚3)对于消息队列所在的系统熟悉:其中就涉及需要非常了解操作系统和当前系统的架构最后就是充分利用当下的消息队列追加一些适合自己业务场景的算法:调整优化当下所用的消息队列。
    展开
    
     8
  • 付永强
    2019-09-03
    可以通过在进行更新数据库操作时,删除缓存,读取数据库时如果有缓存就直接读,没有缓存则从数据库读取并更新缓存,这样的设计可以确保缓存幂等。
     2
     4
  • 岁月安然
    2019-08-29
    ”⻚⾯位置与尾部的距离。因为越是靠近尾部的数据,被访问的概率越⼤“
    不大理解这句话,尾部指的是啥?当某个客户端正在从很旧的位置开始向后读取⼀批历史数据,是怎么判断与尾部的距离,从而减少这部分的缓存。

    作者回复: 与尾部的距离=最后一个一条消息的尾部位置 - 页面的位置

    这个值越小,说明请求的数据与尾部越近,置换的时候被留下的概率也就越大。

    对于历史数据,由于距离远,这个值会很大,那这些页面在置换的时候被留下的概率就很小,所以很快就会被从内从中置换出去。

    
     3
  • 布小丫学编程
    2019-11-28
    老师,我在github上写了一个lru的实现。https://github.com/fomeiherz/code-snippet/tree/master/lru

    使用了HashMap和Queue一起实现的。使用HashMap保存键值对可以实现O(1)复杂查询,使用队列保存key,头部出队,尾部入队。更新比较复杂,需要删除对应的元素后,才可以再入队,这里是O(n) 复杂度。

    老师,更新队列顺序时是否会有更快办法?或者有更快的实现办法呢?求指导
    展开

    作者回复: 你这个实现中,命中缓存后“移动元素到尾部”这个操作,同时会移动其它无关的元素的位置(从队头移到队尾),这样就不满足LRU的原则了,可以试试将队列换成链表这种可以支持随机写的数据结构。

    
     1
  • Yasir
    2019-11-07
    交作业,双向链表实现
    https://github.com/tuhao/leetcode/blob/master/src/mqexercise/LRUTest.java

    作者回复: 👍👍👍

    
     1
  • Switch
    2019-10-24
    参考@A9 的写了一版链表的,然后又写了一版基于 优先队列的。
    https://github.com/Switch-vov/mq-learing/tree/master/src/main/java/com/switchvov/cache
    
     1
  • ponymm
    2019-08-29
    “找不到会触发一个缺页中断,然后操作系统把数据从文件读取到 PageCache 中,再返回给应用程序” 这里pagecache中没有数据并不会产生缺页中断,而是alloc page,然后放入lru链表中,接着调用a_ops->readpage()读取数据到page,可以参考kernel的 do_generic_mapping_read 函数
     1
     1
  • 小伟
    2020-01-22

    作业:https://github.com/ToddSAP/Geektime/tree/master/src/mqmaster/course16/lru
    参考HashMap用array+doubly linked list实现了一个数据结构,提供了LRU的功能。
    
    
  • 付锐涛
    2019-11-11
    置换时机:实时,定期,事件
    
    
  • A9
    2019-10-27
    JMQ是如何使用自定义的LRU算法的?即使使用DirectBuffer不是也要经过PageCache吗?

    作者回复: DirectBuffer确实也需要经过PageCache,但是它有更好的批量大小,写入时的系统调用次数也会更少,所以性能更好一些。

    
    
  • Pitcher
    2019-09-27
    https://gist.github.com/mrpanc/2cf2e668eab099114e0a1f99eb44f573 交作业,用go写了一版基础的lru策略
    
    
  • godtrue
    2019-09-24
    缓存的速度理论上比磁盘快十万倍,那对性能的提升是多么的立竿见影——性能提升的神器。
    而且一级不行可以再来一级,我正好也在压测,用不用本地缓存,性能可以说会差上几十倍之多。
    具体缓存怎么用,还需根据自己的实际业务场景而定。我们redis缓存是每晚定时跑的,也可以人工触发,分为全量和增量,本地缓存是读redis缓存时添加的,为了防止不存在的key加重redis缓存的负载,会将一个特殊值写入本地缓存,以做标识。
    
    
  • 13761642169
    2019-09-22
    PageCache是OS提供的能力,用户程序调用什么API才能使用到PageCache,为什么说kafka大量使用到PageCache,因为mmap?

    作者回复: 对应的几个写文件的系统调用都会经过PageCache,比如write pwrite还有mmap

    
    
  • 泛岁月的涟漪
    2019-09-09
    public class DefaultLruCache<K, V> extends LruCache<K, V> {

        private LruCacheImpl<K, V> cache;

        public DefaultLruCache(int capacity, Storage<K, V> lowSpeedStorage) {
            super(capacity, lowSpeedStorage);
            cache = new LruCacheImpl<>(capacity, true);
        }

        @Override
        public V get(K key) {
            V value = cache.get(key);
            if (value == null) {
                value = lowSpeedStorage.get(key);
                cache.put(key, value);
            }
            return value;
        }

        class LruCacheImpl<K, V> extends LinkedHashMap<K, V> {

            public LruCacheImpl(int capacity, boolean accessOrder) {
                super(capacity, 0.75F, accessOrder);
            }

            @Override
            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
                return size() > capacity;
            }
        }
    }
    展开
    
    
  • 明日
    2019-09-03
    Java实现: https://gist.github.com/imgaoxin/ed59397c895b5a8a9572408b98542015

    作者回复: 👍👍👍

     2
    
  • 木木木
    2019-09-03
    缓存和db的一致性有很多工作做的。文中三种方法,定时更新全部缓存估计只适合量小的,更新不频繁的配置性数据。定时的时间也有问题,太短影响性能,太长一致性问题。设置缓存时间也是类似的问题。我们业务中实际使用同步更新的方式,当然异步也可以。关键是在业务代码落库时落缓存补偿的记录,里面带序号,用来解决异步问题。更新后还可以进行一致性检查
    
    
  • 0xDDE58
    2019-09-02
    期待JMQ开源
    
    
  • 约书亚
    2019-09-01
    来晚了,根据jms和kafka这两节,我试着猜想一下jms的机制,顺便提个问题:
    1. 老师这节提到的jms实现的缓存机制,都是基于direct buffer自己实现的一个内存池,并实现了变种的LRU对么?这个缓存就是前面提到的journal cache,被writeThread/RelicationThread/FlushThread使用?
    2. 这个内存池看起来并没有借助于netty的direict buffer pool是吧?
    3. 那原谅我对比一下jms和rocket,jms没有基于mmap去做而选择direct buffer,看起来是为了:
    a. 减少GC的压力
    b. 比mmap更容易控制,就更容增加缓存的命中率
    这样?
    4. 另外,有个概念我很模糊,有资料说direct buffer在写磁盘/socket时并不能真的节省一次cpu copy?那这样的话jms可以说并没有利用zero copy?

    望解惑
    展开

    作者回复: A1:是的。
    A2:是的。
    对于问题3和4,你可以看一下关于JMQ的这篇文章:
    https://www.jiqizhixin.com/articles/2019-01-21-19

    
    
我们在线,来聊聊吧