加入收藏 | 设为首页 | 会员中心 | 我要投稿 唐山站长网 (https://www.0315zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

或将允许厂商向华为销售芯片,5G 除外

发布时间:2021-02-06 13:07:19 所属栏目:外闻 来源:互联网
导读:当项目的请求量上去了之后,通常有两种做法来应对高并发,第一是尽最大可能的使用cache来对抗,第二是尽最大可能的分库分表对抗。。。说起来容易,做起来并不那么乐观,这一篇就来浅析下。 一:如何保证缓存一致性 如我们的千人千面系统中,会针对商品,订单

当项目的请求量上去了之后,通常有两种做法来应对高并发,第一是尽最大可能的使用cache来对抗,第二是尽最大可能的分库分表对抗。。。说起来容易,做起来并不那么乐观,这一篇就来浅析下。

一:如何保证缓存一致性

如我们的千人千面系统中,会针对商品,订单等多维度为某一个商家店铺自动化建立大约400个数据模型,然后买家在淘宝下订单之后,淘宝会将订单推送过来,订单会在400个模型中兜一圈,从而推送更贴切符合该买家行为习惯的触达,为了应对高并发,这些模型自然都是缓存在Cache中,如果有新的模型进来了,我如何通知redis进行缓存更新呢?通常的做法就是在添加模型的时候,顺便更新redis。。。对吧,如下图:
 

你可以惊喜的发现 mheap.sysAlloc 里其实有调用 sysReserve 方法,而 sysReserve 方法又正正是从 OS 系统中保留内存的地址空间的特定方法,是不是很惊喜,一切似乎都串起来了。

小结

在本节中,我们先写了一个测试程序,然后根据非常规的排查思路进行了一步步的跟踪怀疑,整体流程如下:

  • 通过 top 或 ps 等命令,查看进程运行情况,分析基础指标。
  • 通过 pprof 或 runtime.MemStats 等工具链查看应用运行情况,分析应用层面是否有泄露或者哪儿高。
  • 通过 vmmap 命令,查看进程的内存映射情况,分析是不是进程虚拟空间内的某个区域比较高,例如:共享库等。
  • 通过 dtruss 命令,查看程序的系统调用情况,分析可能出现的一些特殊行为,例如:在分析中我们发现 mmap 方法调用的比例是比较高的,那我们有充分的理由怀疑 Go 在启动时就进行了大量的内存空间保留。
  • 通过上述的分析,确定可能是在哪个环节申请了那么多的内存空间后,再到 Go Runtime 中去做进一步的源码分析,因为源码面前,了无秘密,没必要靠猜。

从结论上而言,VSZ(进程虚拟内存大小)与共享库等没有太大的关系,主要与 Go Runtime 存在直接关联,也就是在前图中表示的运行时堆(malloc)。转换到 Go Runtime 里,就是在 mallocinit 这个内存分配器的初始化阶段里进行了一定量的虚拟空间的保留。

而保留虚拟内存空间时,受什么影响,又是一个哲学问题。从源码上来看,主要如下:

  • 受不同的 OS 系统架构(GOARCH/GOOS)和位数(32/64 位)的影响。
  • 受内存对齐的影响,计算回来的内存空间大小是需要经过对齐才会进行保留。

总结

我们通过一步步地分析,讲解了 Go 会在哪里,又会受什么因素,去调用了什么方法保留了那么多的虚拟内存空间,但是我们肯定会忧心进程虚拟内存(VSZ)高,会不会存在问题呢,我分析如下:

  • VSZ 并不意味着你真正使用了那些物理内存,因此是不需要担心的。
  • VSZ 并不会给 GC 带来压力,GC 管理的是进程实际使用的物理内存,而 VSZ 在你实际使用它之前,它并没有过多的代价。
  • VSZ 基本都是不可访问的内存映射,也就是它并没有内存的访问权限(不允许读、写和执行)。

思考

看到这里舒一口气,因为 Go VSZ 的高,并不会对我们产生什么非常实质性的问题,但是又仔细一想,为什么 Go 要申请那么多的虚拟内存呢?

总体考虑如下:

  • Go 的设计是考虑到 arena 和 bitmap 的后续使用,先提早保留了整个内存地址空间。
  • Go Runtime 和应用的逐步使用,肯定也会开始实际的申请和使用内存,这时候 arena 和 bitmap 的内存分配器就只需要将事先申请好的内存地址空间保留更改为实际可用的物理内存就好了,这样子可以极大的提高效能。

(编辑:唐山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读