39 | 高性能的关键:shared dict 缓存和 lru 缓存
温铭
该思维导图由 AI 生成,仅供参考
你好,我是温铭。
在前面几节课中,我已经把 OpenResty 自身的优化技巧和性能调优的工具都介绍过了,分别涉及到字符串、table、Lua API、LuaJIT、SystemTap、火焰图等。
这些都是系统优化的基石,需要你好好掌握。但是,只懂得它们,还是不足以面对真实的业务场景。在一个稍微复杂一些的业务中,保持高性能是一个系统性的工作,并不仅仅是代码和网关层面的优化。它会涉及到数据库、网络、协议、缓存、磁盘等各个方面,这也正是架构师存在的意义。
今天这节课,就让我们一起来看下,性能优化中扮演非常关键角色的组件——缓存,看看它在 OpenResty 中是如何使用和进行优化的。
缓存
在硬件层面,大部分的计算机硬件都会用缓存来提高速度,比如 CPU 会有多级缓存,RAID 卡也有读写缓存。而在软件层面,我们用的数据库就是一个缓存设计非常好的例子。在 SQL 语句的优化、索引设计以及磁盘读写的各个地方,都有缓存。
这里,我也建议你在设计自己的缓存之前,先去了解下 MySQL 里面的各种缓存机制。我给你推荐的资料是《High Performance MySQL》 这本非常棒的书。我在多年前负责数据库的时候,从这本书中获益良多,而且后来不少其他的优化场景,也借鉴了 MySQL 的设计。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入介绍了在 OpenResty 中关键的高性能组件——缓存的使用和优化。首先,文章介绍了缓存的基本原则,强调了越靠近用户请求越好的原则,并提出了在 OpenResty 中使用共享字典缓存和 lru 缓存的重要性。重点讨论了共享字典缓存中的性能相关问题,包括缓存数据的序列化和 stale 数据的处理。文章还提到了通过 get_stale 方法获取已过期数据的应用场景,以及如何判断数据源中的数据是否发生了变化。此外,文章还介绍了 lru 缓存的接口和版本号的概念,以及如何通过版本号来减少对数据源的压力,达到性能的最优。最后,作者鼓励读者在使用 OpenResty 过程中,结合业务需求和文档,不断探索和领悟,以产生最大的优化效果。整体来看,本文通过介绍缓存的设计和优化,为读者提供了在 OpenResty 中提升系统性能的关键技术和方法。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《OpenResty 从入门到实战》,新⼈⾸单¥59
《OpenResty 从入门到实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(8)
- 最新
- 精选
- Shliesce正在写一个与consul联动动态更新upstream的插件,我们之前使用的微博upsync模块功能不是太理想。目前我也是把upstream信息放在shared dict中的,因为consul自带的就有long polling和index,我考虑把index和value分别存在两个shared dict中,这样定时器只会频繁地访问index这个shared dict,减少全局锁对其他worker的影响,但是我估计性能还达不到我们产线量级的要求,就像老师说的每次请求都要反序列一次,后续可能会再引入lru cache。。老师有什么好的建议吗?
作者回复: 建议看看 lua-resty-mlcache,等于多加一层 lru cache。mlcache提供了 `l1_serializer`,专门用于处理 shared dict 提升到 lru cache 时候对数据的处理,可以尽可能的减少序列化。
2019-08-231 - ch3cknulllru缓存 示例部分的链接失效了,这个链接可用 https://github.com/apache/apisix/blob/master/apisix/core/lrucache.lua2021-10-191
- 小胡子判断数据是否发生了变化,下面函数中的version怎么来的呢。。2021-08-181
- Cobol采用 Kong 的 Proxy-Cache 去缓存大文件(>80M)的时候,wget 的速度比直接下载还慢,应该是与 cjson 的反序列化有关。如果要调优,是要调整共享内存大小吗?2021-03-09
- 卫智雄嗨~,请教一下, 我使用 ngx.shared.DICT.incr 方法, 发现 value 会跳变 下面是我得配置和测试方式 ``` lua_shared_dict counter_ip_dict 100m; server { listen 80; server_name test.com; access_by_lua_block { local ngx_var = ngx.var local counter_ip_dict = ngx.shared.counter_ip_dict local remoteIp = ngx_var.remote_addr local function limitRate(limitKey, maxReqs, expTime) local ipCount = counter_ip_dict:get(limitKey) -- ngx.say(ipCount) if ipCount == nil then counter_ip_dict:add(limitKey, 1, expTime) else if ipCount > maxReqs then ngx.print('ipCount: ') ngx.say(ipCount) ngx.exit(200) else counter_ip_dict:incr(limitKey, 1) end end end limitRate(remoteIp, 10, 20) } location / { root /data/html; index index.html; } } ``` ``` for((i=1;i<12;i++));do echo "-----$i----" ; curl -s -w "http_code: %{http_code}\n" -H 'Host: test.com' 127.0.0.1 ; done ```2020-06-11
- 许童童跟着老师一起精进。2019-08-23
- helloworld赞👍2019-08-23
- Rye正在写API网关的插件,也用了sharedict,感谢老师的思路。sharedict和lru确实有点难两全的感觉。2019-08-23
收起评论