存储系统实战-0
基础的认识
凡是那些特别难解决的、让你付出巨大代价的,或者损失惨重的技术问题,几乎都可以归结为存储系统的问题
存储是系统中最核心、最重要、最关键的组成部分,没有之一
MySQL、Redis、ElasticSearch、HBase、Hive、MongoDB、RocksDB、CockroachDB 等等,这些存储还真就是谁都替代不了谁,每一种都有它擅长的地方,有它适用的场景,当然也有很突出的短板。如何根据业务系统的特点,选择合适的存储来构建我们的系统,这也是需要学习和掌握的
如何保证数据准确无误
合格的订单系统,最基本的要求是数据不能出错
如何避免重复下单
- 让订单服务具备幂等性
- 任意多次执行所产生的影响均与一次执行的影响相同
- 利用数据库主键的唯一性约束来解决创建订单服务的幂等性问题(自定义一个订单号生成的服务)
如何解决ABA问题
对数据的更新也要注意ABA问题
- 什么是ABA问题
- 一个简单的例子,假如有两次请求,第一次要求把数据修改为666,当数据库修改成功,在返回响应的时候失败了,而此时第二个请求到了,要把数据修改为888,并且响应成功了。由于第一次申请没有收到正确的响应,所以进行了重试,这时数据又修改成了666。
- 怎么解决呢?
- 给数据库表增加一列version,也就是版本号的意思,每次查询version都随着数据返回,再更新的时候把version作为更新请求的参数,发送给更新服务
- 更新服务在接收到请求后,对比当前数据的version,是否与请求中的一致,如果不一致就拒绝更新。如果一致,就更新数据的同时把version+1。当前这个更新的过程必须在同一事务里面
商品详情页如何设计
商品都包括哪些信息
商品基本信息如何存储
- 商品基本信息的主副标题、价格、颜色等基本、主要属性,都是固定的。数据量不大,建议在数据库中建一张表来保存商品基本信息。然后在数据库前面加一道缓存,基于内存的KV存储。
- 前置缓存缓存商品数据,读取请求流程:
2.1. 先去缓存查找,如果找到就直接返回数据
2.2. 如果没有找到就去数据库查询,把返回结果返回,并缓存一份到缓存 - 更新时,在更新数据库的同时也要把缓存给删除,来保证数据一致性(Cache Aside缓存更新策略)
设计商品信息表时,一定要记得保留商品数据的每一个历史版本
缓存更新策略
- Cache Aside
- Read/Write Through
- Write Behind
商品参数如何存储
使用MongoDB保存商品参数,和商品的基本属性一样,都是结构化数据,不同类型的商品,它的参数也完全不一样。
MongoDB
MongoDB是一个面向文档存储的NoSQL数据库,在MongoDB中,表、行、列对应概念:Collection、document、field。
表结构是不需要事先定义,MongoDB没有表结构。支持把任意数据放在同一张表中。
MongoDB中的每一行数据,在存储层就是简单地转化成BSON格式。这是一种更紧凑的JSON,MongoDB 不支持 SQL,多表联查和复杂事务比较孱弱,不太适合存储一般的数据。对于商品参数信息,数据量大、数据结构不统一,这些 MongoDB 都可以很好的满足。我们也不需要事务和多表联查,MongoDB 简直就是为了保存商品参数量身定制的一样。
图片和视频如何存储
保存在对象存储中
对象存储
对象存储可以简单理解为一个无限容量的大文件 KV 存储,它的存储单位是对象,其实就是文件,可以是一张图片,一个视频,也可以是其他任何文件。每个对象都有一个唯一的 key,利用这个 key 就可以随时访问对应的对象。基本的功能就是写入、访问和删除对象。
商品介绍如何存储
商品介绍的文本,一般都是随着商详页一起静态化,保存在 HTML 文件中
Tomcat 能能抗的并发量和 Nginx 完全不是一个数量级的
商详页静态化之后,不仅仅是可以节省服务器资源,还可以利用 CDN 加速,把商详页放到离用户最近的 CDN 服务器上,让商详页访问更快。
商品系统的存储需要提供商品的基本信息、商品参数、图片和视频以及商品介绍等等这些数据。商品的基本信息和商品参数分别保存在 MySQL 和 MongoDB 中,用 Redis 作为前置缓存,图片和视频存放在对象存储中,商品介绍随着商详页一起静态化到商详静态页中。