现身说法:实际业务出发分析百亿数据量下的多表查询优化
今天给大家带来的讨论主题是通过实战经验来对百亿数据量下的多表数据查询进行优化,俗话说的好,一切脱离业务的架构都是耍流氓,接下来我就整理一下今天早上微信群里石头哥给大家分享的百亿数据量多表查询架构以及优化思路。由于本文内容整理自微信群,爬楼不易,整理更不易,如果有遗漏,欢迎大家在评论区留言。
简单引子一个例子引出主题
♚
这里我们先举个简单的例子,来个开胃菜,然后再引出今天的访谈主题。
举例:比如我们的CzarCms系统权限系统设计中的两张表:用户表以及角色表,这两张表有关联关系。这时候如果我要取一万个用户的数据,然后用户数据又需要关联角色表来查询对应的角色名称,这时候你会怎么做呢?
按照以往我们的经验我们会对大表进行尽可能的拆分,能分表就分表。我们在取数据的时候使用下join查询即可实现。
可是,当我们的系统变得足够大的时候,假设我们的用户表有一百万的用户了,角色表也有近10万的数据,这个时候我们如果还继续使用Join进行查询的时候就会变得非常慢了!
这时候我们可以改变下思路:就是先把一万条用户数据取出来,然后取所有角色id后再去重的组合,然后用一个查询把所有的角色信息取出来,再在内存中进行相应的拼接处理。这种思路勉强能够支撑。
可是如果数据量变得越来越大,这时候我们应该如何来进行处理呢?且看下面来自百亿数据实操的经典访谈。
业务场景分析实际业务触发
场景介绍
这里,石头哥就以他们公司的实际情况为例来进行了相关的实例阐述:
我们的主要表,都是几亿到几十亿行,一个join不小心就可以弄死数据库,
而且每天1亿包裹在路上,产生3亿多扫描数据
数据存储最少T+1,保存完整的一个月,也就是30到60天
数据量90到180亿
这里面,最常见的就是省,市,区,网点,人员,这5个字段
很久以前,我们只有三五百万业务量的时候,大家都是join五次
后来为了省事,用了10个字段,提前把名称写进去
再后来,发现亏大了
多花了好多空间,并且join不一定是只需要名称字段
于是,进入了新时代,所有数据表都有那基本的5个字段,不许join
查询出来数据后,在内存中再关联省,市,区,网点,人员等信息
地区5万行,网点3万行,人员100万,全部提前加载到内存,加起来不到100M
我们小部门有100台服务器,绝大部分用到这些基础数据
不仅仅上百亿的扫描表,其它业务表,几乎都会带有这些字段,所以,缓存基础数据,不吃亏
互动环节
1. 多大的数据量,才不能用join?
答:一般来说,从表100万以内,我们都建议内存缓存,10万以内必须用进程内缓存,没得商量,内存中进行关联即可。
2. 我们删数据只能一条条删。不允许批删除,这个怎么办?
答:你们DBA可以辞退了,这么简单的事情都不会。
大数据分析的时候,每个月几个亿数据,一条条删,删到何年何月啊,当然是整个分区干掉啦
3. 可以分享一下你们的缓存方案吗?
这个就不用了吧,我觉得很多大佬关于缓存的文章就写得非常好!
我这里只补充一些量化的数字:内存速度是Redis速度100倍,Redis缓存速度是数据库至少10倍。
10万以内数据量必须缓存在进程内,100万~1亿数据缓存在Redis,10万~100万可以上下商量,超高查询量(比如每天10亿次)时放内存。
很多文章真的写得挺好的,就是少了点经验数据支撑,读者搞不清楚什么时候该用这个,什么时候该用那个。
4. 吉吉:以下场景:假设缓存了地区,比如查询人员档案信息列表是1万行 以前是关联查询 现在缓存地区不能关联查询 只能查出一万条然后循环拼接地区显示 ,因为一万行显示本身这场景就不可能,所以增加翻页 一页显示20行 完全不会性能问题 这样做对吗 求教?
答:是的,查询一页20行,理论上要去匹配20次地区,但是地区数据少,省市区才四五千行,省市区加上乡镇街道也不过5万行,可以全量缓存到内存。
吉吉:明白 谢谢 只是举例 这种思路真的很正确 我们总是从技术考虑全部场景却不考虑产品本身根本不能一劳永逸的搞。
5. 真是太牛逼了!感谢分享
答:这么Low的办法,大家都可以想得到,只是可能缺少一个遇到这个数据量的机会罢了,这是咱们.net的际遇,遇到问题可以见招拆招.
6. 你说的缓存到进程内,那多个进程内数据怎么保持一致?
答:不保持一致,因为进程级缓存,可以定时更新的,我们方案是默认10秒异步更新缓存,然后也可以按照添删改随时更新。
7. 我的内存数据以哪个为准?如果我机器是负载均衡,那么几个副本内存不一样啊!
答:以本机为准,没关系,每台服务器上都有一份缓存。缓存10万用户信息,一共也就10M左右内存,你还在意?
8. 数据怎么进行存储呢?
答:内存字典进行存储,最常用的就是并行字典 ConcurrentDictionary。
9. 假设你说的人员数据,那就必然存在 某一时刻 A进程10000人,B进程10002人,可能十秒可能八秒,但你们体量这么大,这个问题不需要处理吗
答:没错,的确存在这样的问题,我们公司有100万人员,但是全公司都知道,新加一个帐号,往往要两三天才能在100多个内部系统全部生效,甚至新签约一家网点,也要两三天以后,各个系统才会认它,等你有那个体量的时候,就可以接受更长的不一致时间,我们在淘宝开店,发布商品,有时候发布成功了,跳转到详情页却是看不到的,等几秒就好了。
另外,
我再说一句恶心一点的情况,大家别拍砖啊,在百亿级数据量之下,就算我算错个几百几千,那又怎么样???又怎么样??
对内,我会严格要求部门人员,务必追求准确;
对外,我会反复提醒部门人员,我们提供的数据精度,最高99.99%,你要敢浪费大量时间在0.01%上,我就敢给你绩效C
不用太死板嘛,把整体工作搞定,让系统稳定工作,那才是咱们的主要工作
用户有万分之一的机会看到不正确的数据,只要再刷新一次能够正确,就一定不是bug
万分之一看到不正确的数据,并且只是万分之一的偏差而已
由此换取的好处是,我们再也不用担心各种该死的“数据一致性。
TOP
1
总结
END
今天非常感谢石头哥的精彩分享,相信只有实际的业务操作经验才会有如此深刻的讲解!一切从实际业务出发,脱离理论,实践出真知。还是印证了那句话,一切脱离实际业务的架构都是耍流氓!感谢大家的阅读。
有想进一步了解石头哥的可以这篇文章《[论一个程序员的自我修养-从一张图片说起](https://www.cnblogs.com/yilezhu/p/10249547.html)》
最后为石头哥的XCode打个广告:
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。
xcode在2018年已经完成对大数据场景的特殊优化改造,2019年的目标是是针对分布式数据场景的优化。
最近石头哥也在为XCode编写系列教程:
整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含多年开发经验于其中,代表作有百亿级大数据实时计算项目。
开源地址:[https://github.com/NewLifeX/X ](https://github.com/NewLifeX/X)(求star, 670+)
现身说法:实际业务出发分析百亿数据量下的多表查询优化相关推荐
- 百亿数据量下,掌握这些Redis技巧你就能Hold全场
来源:https://0x9.me/aos9t 一.Redis封装架构讲解 实际上NewLife.Redis是一个完整的Redis协议功能的实现,但是Redis的核心功能并没有在这里面,而是在NewL ...
- opencv2 取二进制数据_百亿数据量下,掌握这些Redis技巧你就能Hold全场
程序猿DD 一.Redis封装架构讲解 实际上NewLife.Redis是一个完整的Redis协议功能的实现,但是Redis的核心功能并没有在这里面,而是在NewLife.Core里面. 这里可以打开 ...
- Redis基本使用及百亿数据量中的使用技巧分享
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9941208.html 作者:大石头 时间:2018-11-10 晚上20:00 地点:钉钉群(组织代码B ...
- 大数据量下,身份证的查询优化
大数据量下,身份证的查询优化 这里是测试练习采用select *,实际场景中还是使用所有字段的形式,这样也可以提高效率 方式一:身份证分别正向.逆向存储,使用like逆序模糊查询,满足最左匹配原则,索 ...
- 掌握这些 Redis 技巧,百亿数据量不在话下!
一.Redis封装架构讲解 实际上NewLife.Redis是一个完整的Redis协议功能的实现,但是Redis的核心功能并没有在这里面,而是在NewLife.Core里面. 这里可以打开看一下,Ne ...
- 040、JVM实战总结:案例实战:每日百亿数据量的实时分析引擎,为啥频繁发生Full GC ?
1.上文案例再分析 2.一个日处理上亿数据的计算系统 MySQL数据库以及其他数据源里提取大量的数据加载到自己的JVM内存里来进行计算处理. 总负载:每分钟大概需要执行500次数据提取和计算的任务 ...
- mysql 百亿数据_从SQL Server到MySQL,近百亿数据量迁移实战
沪江成立于 2001 年,作为较早期的教育学习网站,当时技术选型范围并不大:Java 的版本是 1.2,C# 尚未诞生,MySQL 还没有被 Sun 收购,版本号是 3.23.工程师们选择了当时最合适 ...
- 面试官问:上亿数据量下,Kafka是如何优化JVM GC问题的?
大家都知道Kafka是一个高吞吐的消息队列,是大数据场景首选的消息队列,这种场景就意味着发送单位时间消息的量会特别的大,那既然如此巨大的数据量,kafka是如何支撑起如此庞大的数据量的分发的呢? 今天 ...
- jvm性能调优实战 -33每日百亿数据量的实时分析引擎,如何定位和解决频繁Full GC问题
文章目录 Pre 运行程序用的示例JVM参数 Code 基于jstat分析程序运行的状态 对JVM性能进行优化 小结 Pre jvm性能调优实战 - 27亿级数据量的实时分析引擎,为啥频繁发生Full ...
最新文章
- 什么是奇异值?奇异值分解是什么?SVD分解详解及实战
- int main( int argc , char *argv[] , char *envp[] )中参数解说
- java hellowordk_Rhythmk 一步一步学 JAVA(4):Spring3 MVC 之 Hello Word
- DevExpress右键菜单使用 zt
- Python连接Mysql数据库SQL注入问题的解决
- nginx+tomcat
- SAP CRM Genil Text-for-Key-Codes vs SAP C4C只读字段
- 无任何网络提供程序接受指定的网络路径 or No network provider accepted the given network path 的解决方法...
- LINUx打包命令汇总
- 商城左侧菜单栏网页模板
- 网站集成QQ登录功能
- fiddler打开后 浏览器就上不了网的解决方法
- MySql基本的操作
- STM32F103ZET6+ADF4351+HMI串口屏
- 微信小程序 组件传值(一) properties 父传子
- ThinkPad键盘拆解与清理(附图详解)
- 搭建微信多开服务器,电脑微信多开你都不会?教你简单实现
- rⅰd的意思_自动挡车上的P、R、N、D、L代表什么意思?老司机也搞晕了!
- 填词作文:新的一年,新的梦想
- 计算机毕业设计,vue+springboot的农产品溯源系统,内附源码