高并发下的海量数据处理

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 前言文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger种一棵树最好的时间是十年前,其次是现在

絮叨


移动互联网时代,高并发下的海量的用户数据每天都在产生,基于用户使用数据等这样的分析,都需要依靠数据统计和分析,当数据量小时,数据库方面的优化显得不太重要,一旦数据量越来越大,系统响应会变慢,TPS直线下降,直至服务不可用。


业务背景


今天呢?其实就是想把自己公司题库业务下的架构梳理一下,当然不是什么牛逼的公司,可能说自己接触的东西,不是那么的牛皮,但是好歹自己也总结一下嘛,公司属于一个线上线下的教育公司,那么题库当然是支撑公司许多业务的底层基石了,当然我来了公司也不是那么久,但是目前题库业务也已经重构了2次了。今年2020年是第三次。下面我先来梳理一下存储设计流程吧

  • 第一阶段 2015年到2018年,当时据说公司是给外包公司做的一个题库系统,因为当时的体量不大,研发之类的原因吧,反正就是外包给人家了,第一阶段,当时据说是采用.Net+sqlserver 做的,然后后面系统维护呀,系统反应之类的慢,因为做题记录我们当时采用的是做一个题就存一个数据,可想而知慢慢的数据量就超过500W了,毕竟业务量也是越来越大。
  • 第二阶段,2018年的重构,当时我也还没来公司,把数据迁移到了 hbase上就是做题数据,所以采用的就是hbase+mysql的存储方式,但是我们用的是phoniex这个其实对于写业务的我们来说,在代码层面是没有啥改变的,其实phoniex对于oltp的业务还是蛮好的,比如索引,多表联查还是可以的,但是就是对于olap业务,就感觉力不从心了,很多业务的报表就会导致了事务事件长,导致hbase写入超时,等等问题就出现了,后面的解决方案就是说主从架构,把报表业务查从库,才解决了这个目前,当时数据量的做题数据已经达到了40亿,但是写入和少量的针对索引的查询,还是在100ms 以内,快还是可以的,但是对于oltp业务就有点力不从心的,然后因为当时2018年的重构呢,很多业务是直接抄的第一阶段的业务代码,经过了几年的开发,几年的人员变更,加上文档的齐全,导致维护,和迭代的成本越来越大,所以我们不得不考虑重构这个题库系统(重构系统的最大难处就是数据和业务的让用户无感知的迁移,这个有机会的话我再写文章来阐述)
  • 再我们技术总监和产品总监的敲定下,决定对公司的所有的教务 教学, 教研 ,全自动自适应学习系统的全方面的重构,题库业务当然是首当其冲,当然其实重构之前的业务梳理,然后报表梳理,架构设计,模块设计,数据同步,系统并行,高并发设计,支撑上千校区数万学员同时考试了,等这些我先不阐述,我们来关注对于海量数据存储的方案讨论,然后我们采用的架构就是mysql+es+hbase+clickhuose的组合来应对题库全场景,全方位的业务,首先做题记录存在hbase+clickhuose中,然后试题和试卷就放到mysql+es中。反正听上面的人说,就是目标做成10年内架构不变的打算,哈哈,针对上面的这些业务背景,小六六想和大家来探讨一下,目前市面上主流的对于海量数据的处理方式。


海量数据导致性能慢怎么办


优化现有mysql数据库

  • 数据库设计和表创建时就要考虑性能 mysql数据库本身高度灵活,造成性能不足,严重依赖开发人员能力。也就是说开发人员能力高,则mysql性能高。这也是很多关系型数据库的通病,所以公司的dba通常工资巨高。
  • 表字段避免null值出现,null值很难查询优化且占用额外的索引空间,推荐默认数字0代替null。
  • 尽量使用INT而非BIGINT,如果非负则加上UNSIGNED(这样数值容量会扩大一倍),当然能使用TINYINT、SMALLINT、MEDIUM_INT更好。
  • 使用枚举或整数代替字符串类型
  • 尽量使用TIMESTAMP而非DATETIME
  • 单表不要有太多字段,建议在20以内
  • 用整型来存IP


  • 索引
  • 索引并不是越多越好,要根据查询有针对性的创建,考虑在WHERE和ORDER BY命令上涉及的列建立索引,可根据EXPLAIN来查看是否用了索引还是全表扫描
  • 应尽量避免在WHERE子句中对字段进行NULL值判断,否则将导致引擎放弃使用索引而进行全表扫描
  • 值分布很稀少的字段不适合建索引,例如"性别"这种只有两三个值的字段
  • 字符字段只建前缀索引
  • 字符字段最好不要做主键
  • 不用外键,由程序保证约束
  • 尽量不用UNIQUE,由程序保证约束
  • 使用多列索引时主意顺序和查询条件保持一致,同时删除不必要的单列索引 简言之就是使用合适的数据类型,选择合适的索引


总之:一条就是如果我们的mysql还能优化,那就优化它吧,不行就加缓存,就是简单的方法可以完成80% 和难的方法完成95% 那么我们也可以选择简单的方法,难的放到不得不用的时候再来。

总之,能先进行简单优化则没必要引入负责的解决方案,通常数据库刚表现出压力的时候,大部分原因不是因为业务真的发展到数据库撑不住了,而是很多慢查询导致的;


聊聊分库分表


为什么需要分库分表?

请求数太高: 在高并发情况下,大量请求落入数据库,最终会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值。在业务Service层来看就是,可用数据库连接少甚至无连接可用。接下来面临的就是并发量、吞吐量、连接异常、崩溃、宕机;


  • 数据查询慢:
  • 一、单表或单库数据量过大引起的,具体参考第三条;
  • 二、单库整体并发连接数接近系统阈值,从而导致此请求获取不到连接数或者已经获取但是遇到CPU瓶颈,导致SQL所查询的表就算数据行很少也同样出现查询过慢的现象;
  • 数据量太大: -一、当一个库的数据存储量太大时,就算每张表的并发数不多,但是因为是海量数据,单库中存在大量的数据表,每张表都有一部分并发请求,导致最终单库的连接数阈值(最大连接数默认100,最大可设为16384,但是一般按硬件和库的业务属性来合理配置,一般在500-1200之间)成为数据库的瓶颈;
  • 二、当一张表数据太多时也导致单表查询速度严重下降,虽然innoDB存储引擎的表允许的最大行数为10亿,但是如果一张表的数据行记录达到上亿级,那么我就算通过索引去查询一条数据,它也需要至少经过上十次到几十次磁盘IO,从而导致单表查询速度直线下降;一般一张表的数据行为1000万左右是最合适的,因为表数据为1000万时建立的索引如果是B+Tree类型的话一般树高在3~5之间,所以查询的速度自然也是很快速的;
  • 单体架构通病: 单库中遇到问题需要修复时影响了整个库中所有数据,而分库时只需要修复某个库就好了;

其实以上问题都是属于数据库遭遇到了瓶颈,但是只不过根据情况不同分为不同类型的数据库瓶颈,但是最终对于客户端而言就是数据库不可用了或者变慢了。


注意!!! 不要为了分库分表而分库分表!!! 引入SOA架构中的一句话:架构不是一蹶而起的,而是慢慢演进的

至于分库分表的常识性问题,小六六就不在这边阐述了,我觉得每一个后端开发人员至少需要去了解一下它,它的垂直分库,垂直分表,水平分库,水平分表。它的优点(其实就是可以解决单表数据量大的情况下,查询的效率问题,因为mysql 索引的树高在3到4层的时候,查询是好的),然后它的缺点(事务,多表联查,分页,排序)等等,然后要怎么解决这些问题,目前业界也有很多开源框架,mycat,shardingsphere等等等等。其实这也算是一个知识点了,可能小六六后面会出这种文章吧,但是我们今天分库分表只能说是一种海量数据的解决方案


NoSQL/NewSQL


这边说下,例如我们公司使用的hbase,es,redis等都是nosql,他们的特点就是分布式,具有很强的水平拓展能力,

NoSQL/NewSQL作为新生儿,在我们把可靠性当做首要考察对象时,它是无法与RDBMS相提并论的。RDBMS发展几十年,只要有软件的地方,它都是核心存储的首选。

目前绝大部分公司的核心数据都是:以RDBMS存储为主,NoSQL/NewSQL存储为辅!互联网公司又以MySQL为主,国企&银行等不差钱的企业以Oracle/DB2为主。NoSQL/NewSQL宣传的无论多牛逼,就现在各大公司对它的定位,都是RDBMS的补充,而不是取而代之!

最近很火的TiDB就是一种NewSql,小六六公司也没用,但是自己去玩了一把,当然我不是专业的测试人员,对于它的性能我确实不知道到底比其他数据库好多少,但是对于用法来说,我觉得还行,因为你会sql语法,你就会用它,比较简单就能使用。它的TIKV 支持OLTP场景,他的TIflash 支持 OLAP场景,我相信,再5G时代,他会是一款非常好的数据库。


mysql+Nosql方案


目前因为NewSql的普及性,大部分的公司我觉得还是mysql为主+Nosql为辅的方案比较多,大家可以在下面评论留言,讨论一下大家公司的解决方案,

  • mysql(主要数据存储)分库分表+ es(查询 分页 排序)放部分字段+主键

这种方案的话,也是可以的,应该有公司用吧

  • hbase (列式存储 rowkey设计)+es(查询 分页 排序) 部分字段+rowkey
  • solr+hbase(其实这个方案更加成熟,用得估计也更多) 比如说 Lily HBase Indexer。


总结


最后,对几种方案总结如下(分库分表简称为sc):

网络异常,图片无法展示
|

总之,对于海量数据,且有一定的并发量的分库分表,绝不是引入某一个分库分表中间件就能解决问题,而是一项系统的工程。需要分析整个表相关的业务,让合适的中间件做它最擅长的事情。例如有sharding column的查询走分库分表,一些模糊查询,或者多个不固定条件筛选则走es,海量存储则交给HBase。


做了这么多事情后,后面还会有很多的工作要做,比如数据同步的一致性问题,还有运行一段时间后,某些表的数据量慢慢达到单表瓶颈,这时候还需要做冷数据迁移。总之,分库分表是一项非常复杂的系统工程。任何海量数据的处理,都不是简单的事情,做好战斗的准备吧!


结尾


今天就聊这么多吧,下次有机会和大家聊聊对于高并发的处理呗,可能我们的业务场景是做题,所以处理起来就比订单 商品啥的要简单很多,但是我们也是花心思去设计我们的高并发场景的,还有重构后,连表结构都变了,我们是怎么让用户做到无感知的迁移的,反正重构绝不是说新做一个系统那么简单,路还是很长的,除非你能不要以前的数据,那就很简单了。哈哈,其实我们做的也只能是70分吧,做不到满分,不知道大公司是怎么搞重构的,希望有大佬再评论下留言。请注明出处。

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
7月前
|
存储 关系型数据库 OLAP
TiDB适用场景解析:海量数据存储与高并发读写的利器
【2月更文挑战第25天】随着大数据时代的到来,海量数据存储和高并发读写成为众多企业面临的挑战。TiDB作为一种高性能、分布式的关系型数据库,以其独特的架构和强大的功能,在多个场景中展现出了卓越的性能。本文将详细探讨TiDB在海量数据存储、高并发读写等场景下的适用情况,分析其在不同业务场景中的优势与应用价值。
|
7月前
|
监控 Java 数据处理
【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
|
4月前
|
存储 SQL 关系型数据库
(二十一)MySQL之高并发大流量情况下海量数据分库分表的正确姿势
从最初开设《全解MySQL专栏》到现在,共计撰写了二十个大章节详细讲到了MySQL各方面的进阶技术点,从最初的数据库架构开始,到SQL执行流程、库表设计范式、索引机制与原理、事务与锁机制剖析、日志与内存详解、常用命令与高级特性、线上调优与故障排查.....,似乎涉及到了MySQL的方方面面。但到此为止就黔驴技穷了吗?答案并非如此,以《MySQL特性篇》为分割线,整个MySQL专栏从此会进入“高可用”阶段的分析,即从上篇之后会开启MySQL的新内容,主要讲述分布式、高可用、高性能方面的讲解。
330 1
我的收藏:第三章:海量数据和高并发解决方案
我的收藏:第三章:海量数据和高并发解决方案
我的收藏:第三章:海量数据和高并发解决方案
|
SQL 运维 负载均衡
漫谈OB | OceanBase 在海量数据和高并发下的应用实践
数据库选型用 OceanBase 的原因很多,传统数据库上的业务做分布式数据库选型,其中一类原因是数据库遇到瓶颈。这类客户业务特点之一是数据量和访问量都很大。本文总结业务数据量和访问量大的业务场景下的OceanBase实践经验。 💡 本文适用于 OceanBase 企业版和社区版
1106 0
|
7月前
|
消息中间件 Java Linux
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
|
6月前
|
缓存 NoSQL Java
Java高并发实战:利用线程池和Redis实现高效数据入库
Java高并发实战:利用线程池和Redis实现高效数据入库
535 0
|
4月前
|
监控 算法 Java
企业应用面临高并发等挑战,优化Java后台系统性能至关重要
随着互联网技术的发展,企业应用面临高并发等挑战,优化Java后台系统性能至关重要。本文提供三大技巧:1)优化JVM,如选用合适版本(如OpenJDK 11)、调整参数(如使用G1垃圾收集器)及监控性能;2)优化代码与算法,减少对象创建、合理使用集合及采用高效算法(如快速排序);3)数据库优化,包括索引、查询及分页策略改进,全面提升系统效能。
56 0
|
6月前
|
存储 NoSQL Java
探索Java分布式锁:在高并发环境下的同步访问实现与优化
【6月更文挑战第30天】Java分布式锁在高并发下确保数据一致性,通过Redis的SETNX、ZooKeeper的临时节点、数据库操作等方式实现。优化策略包括锁超时重试、续期、公平性及性能提升,关键在于平衡同步与效率,适应大规模分布式系统的需求。
202 1
|
5月前
|
算法 Java 调度
高并发架构设计三大利器:缓存、限流和降级问题之使用Java代码实现令牌桶算法问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之使用Java代码实现令牌桶算法问题如何解决