ARTS-WEEK-014
Algorithm:
622: Design Circular Queue
环形队列(Circular Queue,Ring Buffer)是一种性能更好的队列实现,相比链表对cpu缓存更加友好,相比一般数组队列避免了数据搬移。在实现的过程中需要两个pos,分别是生产者p1和消费者p2(具体p1是下一个生产位置,p2是下一个消费位置),为了区分队空和队满两种情况,需要牺牲一个位置空间(因此内部数组长度要+1),如定义两个pos相等为空,p1下一个位置是p2为满,注意多个操作都需要用取模运算避免越界,当数组长度为2次幂时取模可以优化为位运算加速。该题目中易错点:数组长度+1、注意边界操作(取队首是p2但取队尾是p1减一)以及取模避免数组越界,一次写对需练习。
Review:
Disruptor 是著名的高性能并发队列组件,充分利用了现代 CPU 的缓存和预读特性、零拷贝、低 GC 开销、CAS 或无锁等一系列并发技术,这篇技术论文也是并发知识技术不可多得的总结,例如并发执行聚集于两件事:互斥和可见性等。文中也有关于不同队列实现技术的大量测试数据,以及 Disruptor 核心技术的要点总结,值得多读几遍。
Tip:
Disruptor占用较多CPU资源问题分析
前几天在系统压测中分析CPU的过程中发现一些有趣的问题,这是一个消费消息处理(放入Redis缓存)并转发的应用,当我们不断增加并发请求直到消息消费积压后,可以认为此时系统处于吞吐极限,进而继续分析可优化和提示的地方。此时该实例 CPU 达到 80%,而网络和磁盘IO使用率都不高,进一步通过 top -Ph 和 jstack 分析线程级CPU使用率,发现最高的是发送消息时调用 java.util.zip.Deflater.deflateBytes,即压缩处理,这可以理解并且能通过关闭消息压缩解决。
然而第二CPU使用率高的是 Disruptor 组件调用的 Unsafe.park,该组件来自公司的分布式追踪框架 sgm,经过一番调查发现这是 Disruptor 旧版本的一个问题,在 SleepingWaitStrategy 中通过在循环中使用 LockSupport.parkNanos(1L);
使线程暂停并避免条件变量唤醒的代价,但是不同硬件在 sleep 1 nanos 的时间并不相同,官方文档 提到一般 linux 系统中会暂停 60 µs,但是许多人都提交 issues 反馈出现忙转 busy spin(估计是因为其他环境下最小暂停时间可能更短?1,000 纳秒 = 1微秒 μs,1,000 微秒 = 1毫秒 ms),因此后面新版将其改为可配置参数,并默认提高到 100 ns。
thread: 18711, cpu: 70.00%
stack:
"sgm-disruptor-6-thread-1" #16 daemon prio=5 os_prio=0 tid=0x00007f9401c29800 nid=0x4917 runnable [0x00007f93b5f14000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338)
at com.lmax.disruptor.SleepingWaitStrategy.applyWaitMethod(SleepingWaitStrategy.java:82)
at com.lmax.disruptor.SleepingWaitStrategy.waitFor(SleepingWaitStrategy.java:55)
at com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:56)
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:124)
at java.lang.Thread.run(Thread.java:745)
参考:
https://github.com/LMAX-Exchange/disruptor/wiki/Getting-Started
https://github.com/LMAX-Exchange/disruptor/issues/219
https://stackoverflow.com/questions/12972918/why-does-park-unpark-have-60-cpu-usage
Share:
Two Reasons People Are Immature
我们常常觉得自己或某人不成熟,但是关于为什么不成熟却很难深究细节,这个视频给出了很好的信息和观点,不成熟主要总结为1 低自我价值(low self worth),2 低信任他人(low trust in others)。例如前者带来的无法接受批评、不能坚定和冷静的反驳他人、对他人和世界妄想恐惧、无法展示真实的自己、防御性的自大与脆弱的自我等。后者带来无法信任和反馈给予帮助的人、无法告诉别人自己的需求和感受、对别人攻击和诋毁自己的恐惧、担心别人让自己失望带来的保守和僵化。
这两方面问题都可以追溯到童年时有缺陷的发展,人们无法珍视自己直到有他人珍视,形成一个内在稳固的自我镜像,掌握关爱自己和他人的能力。问题的解决办法则有三个方面,1深刻的理解和剖析过去,2和他人尤其是有类似问题的人沟通,建立联系以改善,3寻找合适的关系(找对象)。