【玩转大厂实际项目】之【存储层】

本文已参与「新人创作礼」活动,一起开启掘金创作之路

大家好,我是桐言无忌,当前是不务正业的攻城狮,信奉“实践出真知,生活更简单”,向往自由。

若有些许启迪、收获,请点个赞,也欢迎大家评论。签名

继续上个话题

通过上一期,大家已经知道元数据 是怎么玩的了。接下来,为了完成千万级别商品数据存储,以及多样化的查询场景,如何设计存储层就尤为关键。

痛点

总不能还小米加步枪,全程使用MYSQL吧。举个例子,存储层2

若是MYSQL存储商品数据,我们要查询颜色是红色,价格是100,品类是衣服,地区是广州的所有商品,那么相对应的sql语句就改这么写: select * from t_goods where 颜色=红色 and 价格=100 and 品类=衣服 and 地区=广州; 若是检索条件更多,and条件就更多。

且不说这个sql语句可以优化,但就这么去执行,相信性能肯定扛不住。有同学说,那就加索引,可是不能每个字段都加索引啊。另外,别忘了,我们的前提是千万级别的商品数据量,MYSQL理论上说单表能达到1千万,但是,实际试试就知道,查询起来贼慢。

又有同学说了,你可以分库分表呀。针对数据量大,查询慢的情况,这是个办法。但不可避免的增大代码的复杂度,不可取。

来,感觉走到这,MYSQL是蹚到尽头了,不在一棵树上吊着,咱们开阔思路。

咱们是这么玩的

系统存储层

用户查询请求到微服务,微服务组装查询条件到ElasticSearch库里面找到满足条件的商品id列表,再根据商品id列表到Cassandra查询商品详情信息。

这里,我们用到了2种数据库,分别是ElasticSearch和Cassandra。选型它们的原因是什么?

为啥选择ElasticSearch?

选项,也许提到ElasticSearch,第一反应就是“搜索引擎”。有点像百度搜索、京东搜索那种。其实并不然。

ElasticSearch可以做得事情很多,业界主要应用有这么几种:日志实时分析报表、搜索服务、时序数据分析。

我的系统选择,就看中了搜索能力。回顾下我们系统的场景:要做全文检索,类似与拼多多、京东这样电商的大量商品的搜索。优点呢,也很多,列几个主要的:

  1. 性能贼佳。单个服务最大达到10W的QPS,咱们搜索的商品,总不能一直转圈圈吧。
  2. 可以有召回率、正确率等指标进行评估改进。
  3. 生态圈丰富,社区活跃,能找到任何想要的资源。

咱们来看看ElasticSearch的查询语句长啥样:json查询请求

JAVA api就更方便了。java查询请求

为啥选择Cassandra?

大家网上搜索,可以搜索出Cassandra的相关信息。我这里选用cassandra,更看重的是它有着MYSQL独有的特长:

  1. 非常简单的查询语句,支持主键查询。所以我查询商品详情的时候,要带着商品id(主键)。

  2. 最终一致性。数据到最后总不能对不上号吧。

  3. 可以存储大量的数据。最喜欢这一点了。

  4. 可以随时加字段列。我们业务不可能一下子就想好所有字段信息,随着版本开发,是有加字段的需求的。

    MYSQL Cassandra
    一旦为表定义了某些列,在插入数据时,在每一行中,所有列必须至少填充一个空值 可以随时向任何列族自由添加任何列
    关系表只定义列,用值填充表 表包含列,或者可以定义为超级列族
  5. java的api特简单。

有了这些,选用cassandra就成了理所当然。

总有点不完美

心细的同学,或许发现,系统中原本是一个MYSQL存储,现在分成了2个ElasticSearch+Cassandra的存储层,那怎么保证两个存储库数据是一致的呢?

确实,两个存储库,入库总有先后之分,那就要想办法保证数据一致性。我们讨论几种场景,看看是哪个场景会出现不一致的情况,好对症下药呀。

  1. 先写入ElasticSearch失败,or 先写入Cassandra失败,后面的操作都不再执行;这个场景不存在数据不一致的问题。
  2. 先写入ElasticSearch成功,再写入Cassandra失败,这时候两个库发生了数据不一致。
  3. 先写入Cassandra成功,再写入ElasticSearch失败,这时候两个库也发生了数据不一致。

对于第2种和第3种场景,其实本质是一致的:不在一个逻辑库上,所以无法保证事务性。

要想保证最终数据一致性的话,我的办法是:记录这次写入失败的商品信息,期待下次回放,重新执行。毕竟失败的是少数,只要保证数据最终一致,系统就是可用的。

Guess you like

Origin juejin.im/post/7067376554325573646