记ElasticSearch的一个有趣的性能问题
背景笔者近期在做一个电商的交易模块,项目中订单相关的信息存储在ElasticSearch中,除去搜索的用途外,由于分布式数据库的sharding字段只有一个,还兼职根据某个特定字段找到某一张订单,避免全表扫描。在对一批接口压测时,发现有个接口A性能非常弱,比较有趣的是,这个接口对ElasticSearch的查询条件与同一批的另一个接口B在某个场景下基本一致,但QPS差异巨大,且A接口压测时ElasticSearch CPU飙升,而B接口压测时维持在很低的水平。
猜测在排查过代码之后,发现两者的查询条件基本一致,但是A接口查询时使用了一个elasticsearchRestTemplate.queryForList方法,而B接口则是elasticsearchRestTemplate.queryForPage,这两个方法的区别在于分不分页,然而,queryForList内部由于es的限制实际上也是分页查询,只是设置默认最大分页大小10000,简单修改后重新压测,发现问题解决了。
理论上到此为止已经解决问题了,但是为什么?明明无论是设置分页大小为10或10000,返回的数据量都是一致的(1-3 ...
golang 1.20 http2源码解读
前言搞清楚linux进程调度后,下一步就是网络。从最常见的http开始,考虑到java源码的冗长以及jvm的naive不透明,不如从golang入手。本次解读基于golang 1.20。
Http 1.1Http1.1应该是web协议中最简单的一个。一句话概括,给每个连接分配一个goroutine,goroutine负责读取请求-处理-发送响应,然后关闭连接或者在这个连接上循环做读取请求-处理-发送响应。这整个过程都是同步且阻塞的。如图:
可以看到,Http1.1对于TCP链接的利用率很低,因为每个连接都是阻塞的,这就导致在Http1时代对于浏览器场景,为了加快速度,浏览器会开多个连接,而对于分布式应用,为了保证并发甚至需要维护一个连接池。而这也直接导致了各种基于TCP的RPC框架的出现,比如dubbo,thrift等等。在这个阶段,RPC最核心的还是自定义协议以支持连接级别的多路服用,Stub反而只是锦上添花。
更糟糕的是每个连接都需要一个线程/协程,对于JAVA这种语言来说是不可接受的。当然,对于Golang来说由于goroutine足够cheap,并且结合epoll和 ...
unix-like操作系统 xv6-riscv
最近在读《深入理解JVM虚拟机》,发现其中的一些概念有些不理解,大抵是对于底层知识不了解。 于是转头去读《OSTEP》这本书,发现是一本很好的入门书,看完有了一些更深的理解,但是,疑问没有变少,反而变多了。 OSTEP中提到了一个叫xv6的小型unix-like os,于是机缘巧合,发现了MIT的6.828课程,在此留存一下xv6的讲义和一些随想。
一些有用的link:MIT6.S081中文视频课程课程文字版xv6中文讲义原版risc-v pri isa注:以下讲义内容来自于上述文档xv6中文讲义原版,侵联删。
第一章:操作系统接口操作系统的工作是将计算机的资源在多个程序间共享,并且给程序提供一系列比硬件本身支持的更有用的服务。操作系统管理并抽象底层硬件,因此,举例来说,一个文字处理程序不需要去关心自己使用的是何种硬盘。操作系统还对硬件进行多路复用,使多个程序可以同时运行的(或者看起来是同时运行)。最后,操作系统为程序提供了一种可控的交互方式,使得多个程序可以共享数据,共同工作。
操作系统通过接口向用户程序提供服务。设计一个好的接口实际上是很困难的。一方面,我们希望接口简单和精准,这样 ...
Linux v5.19 risc-v 进程/线程调度汇编级源码解读
不知不觉毕业已经四年有余。一直在做Java,做的再好终归是Spring上浅浅的一层苔藓,一刮就没了。 偶尔心血来潮看一眼《深入理解JVM虚拟机》也如过眼云烟,也始终不得要领,书籍繁多,却也没有一本是为门外汉准备的。 国内的书籍有种不鼓励自学的傲慢,喜欢假定读者已经有了一定的基础,可惜我是没有的,如果有的话我也不会再去看那本书了。 转而去读《OSTEP》,似进入桃花源的一小口,打开了[MIT6.S081]的大门。 听课的这段时间简直是工作后最快乐的时光,两位教授带领你把CPU/MM/FS层层剖开,边学边觉得知识从一个个孤岛融汇起来,知识在经脉里流淌。 终归,告别XV6之后还是要来Linux朝圣。
前言本文并不是一篇Linux进程入门教程,建议按照顺序掌握以下知识后参考本文理解Linux源码。
Clang基础
OSTEP 操作系统导论 - 这绝对是一本好书,能让你低成本的思考操作系统的本质
MIT6.S081 - MIT的本科操作系统课程,难度颇高,笔者花了两三个月的时间但很值得。
(可选)Linux内核设计与实现 - 本书是Linux内核的入门书籍,但是并算不上入门,对笔者来说 ...
Journaling the Linux ext2fs Filesystem
Journaling the Linux ext2fs FilesystemNotice:It’s a copy from https://github.com/duguosheng/6.S081-All-in-one/blob/main/tranlate_books/Journaling%20the%20Linux%20ext2fs%20Filesystem.mdIt’s translate from https://pdos.csail.mit.edu/6.S081/2022/readings/journal-design.pdf
摘要本文描述了为Linux ext2fs文件系统设计和实现事务元数据日志的工作进展。我们回顾了崩溃后恢复文件系统的问题,并描述了一种旨在通过向文件系统添加事务日志来提高ext2fs崩溃恢复速度和可靠性的设计。
介绍文件系统是任何现代操作系统的核心部分,人们期望它既快速又非常可靠。但是,由于硬件、软件或电源故障,问题仍然存在,机器可能会意外停机。
在一次意料之外的重启后,系统可能需要一些时间才能恢复文件系统的一致性状态。随着磁盘大小的增长,这一时间可能会成 ...
谈谈Http2-为什么nginx在http2下的表现远弱于http1.1
背景本篇文章的灵感来源于不久前的一次压测,接口的TPS在100并发下不足500,且延时超过500MS,这个接口的性能远远低于我们的预期。对应的接口是一个极为简单的接口,只做了两件事情:
从数据库中读取一条数据,做了一些简单的处理
进行一次HTTP调用
那么话不多说,开始从内到外几个排查:
DB的CPU、内存、磁盘IO、网络IO等指标一切正常:排除慢sql相关问题
POD,即容器的CPU、内存、网络IO等指标一切正常:排除容器资源不足问题
JVM的Heap Size即堆内存、GC、线程数等指标一切正常:排除内存泄漏、GC问题
利用Arshas或其他监测工具生成火焰图或接口耗时分析图,发现接口耗时主要集中第二步
Stream Reset Exception上文提到发现接口的主要耗时集中在第二步,那么我们就从第二步开始分析:
排查发现,该Http调用使用的是Okhttp3, 且使用的是默认的连接池,最多复用5个连接,看起来有点太少了,但后续调整到100后发现性能并没有提升,所以这个问题基本可以排除。(当然连接池确实过小,但是与此次的性能问题并无关系)
12345678@C ...
如何实现一个简单可关注/点赞的Feed流
背景笔者新接到一个项目,是某品牌赞助的青春选秀节目打call平台,要求能够实现一个体验良好的Feed流,能够有社交广场/关注/点赞/评论等的功能。
基本思路一条微博的信息一条微博包括文字,图片和视频以及点赞和评论和一些基本发布时间等。根据以上的信息,我们将其拆分为:至此,基本的结构已经出来了。
分表其中根据估计的用户量,主信息在千万级,图/视频/点赞/评论都在亿级,势必要进行分表。二级索引指的是手动维护的表,比如微博主表由于要从两个维度查询,需要针对话题ID和主表ID的关系 额外建一张表,其中字段尽量少,查询时使用leftjoin来关联主表,以下内容皆是如此。此种方式性能略差,可能join时可能会被解析分到多张主表,而且需要在数据更新时同步维护,所以尽量选取合适的主分片键。微博主表:主分片键:用户ID二级索引:话题ID微博图/文/视频/点赞:主分片键:用户ID微博评论:主分片键:主表ID二级索引:用户ID微博关注:主分片键:用户ID二级索引:被关注用户ID
话题广场话题广场是首页,但是由于考虑到F ...
如何设计一个高性能的短链接系统
背景做为刚转正的实习生,最后在PM的指导下设计了一款短链接系统,这里记录一下设计思路和实现细节。
设计思路短链接其实很简单,只要将长链接通过某种算法转换成短链接,然后通过短链接重定向到长链接即可。
设计思路很简单,直接使用一个接口/create创建短链接,并在数据库中存储长链接和短链接的映射关系。另一个/${hashcode}接口用于访问,通过短链接重定向到长链接。
创建短链接创建短链接的接口很简单,直接将长链接转换6位短链接,直接插入并使用数据库唯一键约束,如果短链接已经存在,则对比长链接是否一致,一致返回即可,不一致则是发生了碰撞。在长链接后拼接随机字符即可(入库的还是原链接)。
考虑到刚创建的链接可能会被频繁访问,所以我们在创建链接的时候就将短链接放入Redis缓存中,并设置缓存时间为有效期,这样可以减少数据库的访问。
数据库字段:
long_url: 长链接
tiny_url: 短链接
create_time: 创建时间
update_time: 更新时间
status: 状态
短链接生成算法对于短链接生成算法,可以使用数据库id自增或者雪花算法,也可以 ...