我有一个高吞吐量低延迟应用程序(3000 个请求/秒,每个请求 100 毫秒),并且我们大量使用 Java 8 ConcurrentHashMap
来执行查找。通常这些 map 由单个后台线程更新,并且多个线程从这些 map 读取。
我发现了性能瓶颈,在分析中我发现 ConcurrentHashMap.get
是热点并占用了大部分时间。
在另一个案例中,我看到 ConcurrentHashMap.computeIfAbsent
是热点,尽管映射函数的延迟非常小,并且配置文件显示 computeIfAbsent
花费了 90% 的时间执行自身,并且执行映射函数的时间非常少。
我的问题是有什么方法可以提高性能吗?我有大约 80 个线程同时从 CHM 读取数据。
最佳答案
I have around 80 threads concurrently reading from CHM.
最简单的事情是
- 如果你有一个CPU密集型进程,那么事件线程的数量不要多于你拥有的CPU数量,否则这只会增加开销,如果这些线程在不运行时持有锁,因为你有太多线程,它真的会增加开销。没有帮助。
- 增加分区数量。您将需要至少 4 倍的段/分区数量,并且有访问单个映射的线程。但是,如果您使用超过 40 个线程访问 CHM,由于缓存一致性的工作方式,您会在 CHM 中遇到奇怪的行为。我建议使用更高效的数据结构来实现更高程度的并发性。在 Java 8 中,concurrencyLevel 是一个提示,但它比保留默认初始化大小 16 更好。
- 不要在 CHM 上花费太多时间。找到一种在不占用共享资源的情况下完成有用工作的方法,您的线程将运行得更加高效。
如果您在低延迟系统中看到任何延迟,恕我直言,您就有问题了。
关于performance - Java 8 并发 HashMap 获得性能/替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33901070/