571
社区成员




该系统为一套电子商城系统,用户可以登录、购买商品、查看订单,管理员可以管理用户,商品及订单。为了使得该系统更可靠,可扩展性更强。电子商城系统的数据库采用分布式数据库MongoDB进行开发。
(1)具备用户表,商品表,订单表,用户登录功能,分为普通用户和管理员两种角色。
(2)管理员具备商品的增删改查功能。
(3)管理员具备用户的增删改查功能。
(4)用户具备浏览商品列表功能。
(5)用户下单,使用事务进行扣减库存和订单生成。
(6)订单具有有效期,失效后自动删除并且恢复库存。
(1)前端用户商品列表页面与管理员后台页面采用React,Vue进行开发
(2)搭建分布式数据库MongoDB进行存储数据
(3)具备美观的web页面,操作简易,使用户易于上手。
(1)基于分布式文件存储
(2)存储格式为bson,bson作为json的扩展,可以存储复杂的数据类型
(3)查询语言非常强大,类似于面向对象的查询语言
(4)支持 Golang,RUBY,Python,JAVA,C++,PHP,C#等多种语言
MongoDB的优势:
MongoDB 特性 |
优势 |
事务支持 |
MongoDB 目前只支持单文档事务,需要复杂事务支持的场景暂时不适合 |
灵活的文档模型 |
JSON 格式存储最接近真实对象模型,对开发者友好,方便快速开发迭代 |
高可用复制集 |
满足数据高可靠、服务高可用的需求,运维简单,故障自动切换 |
可扩展分片集群 |
海量数据存储,服务能力水平扩展 |
高性能 |
mmapv1、wiredtiger、mongorocks(rocksdb)、in-memory 等多引擎支持满足各种场景需求 |
强大的索引支持 |
地理位置索引可用于构建 各种 O2O 应用、文本索引解决搜索的需求、TTL索引解决历史数据自动过期的需求 |
Gridfs |
解决文件存储的需求 |
aggregation & mapreduce |
解决数据分析场景需求,用户可以自己写查询语句或脚本,将请求都分发到 MongoDB 上完成 |
主要是由文档(document)、集合(collection)、数据库(database)这三部分组成
一共有三种分布式数据库的集群架构,分别是主从复制,副本集和分片。我们采用的是分片,适合处理大量数据,它将数据分开存储,不同服务器保存不同的数据,所有服务器数据的总和即为整个数据集。
分布式事务在保持多语句操作的完全原子性的同时完成所有这些操作。如果任何事务无法在分片上提交,则会中止该事务中涉及的所有分片操作。使得分布到集群中不同 sharded 的多文档 ACID 事务变得更加简单。MongoDB 通过二阶段提交的方式,实现在多个 Shard 间发生的修改,要么同时发生,要么都不发生,保证事务的 ACID 特性。
(1)2PC(二阶段提交)同步阻塞协议
二阶段提交是一种强一致性设计,2PC引入了一个事物协调者的角色来协调管理各参与者的提交和回滚,二阶段分别指:准备、提交两个阶段,它是一种尽可能保证强一致性的分布式事务,所以它是同步阻塞的,总体而言效率低,而且存在协调者单点故障问题,极端情况下无法保证数据一致性
准备阶段:协调者会给各参与者发送准备命令,它主要是为了对事物进行提交。
提交阶段:同步等待所有资源的响应之后就进入了提交阶段,这里提交阶段并不是只是提交,也可能是表示回滚。
假如在第一阶段有一个参与者失败,那么协调者就会向所有参与者发送回滚请求,也就是分布式失败
如果二阶段提交失败:
① 第二阶段执行的是回滚事务操作,不断重试,直到所有参与者都回滚,否则第一阶段准备成功的参与者会一直阻塞
② 第二阶段执行的是提交事物操作,也会不断重试,因为部分参与者可能成功,只能进行重试,直到重试成功。
(2)Redis消息中间件的应用
Redis不仅可作为缓存服务器,还可用作消息队列。它的列表类型天生支持用作消息队列。
由于Redis的列表是使用双向链表实现的,保存了头尾节点,所以在列表头尾两边插取元素都是非常快的。所以可以直接使用Redis的双向链表实现消息队列,只需 简单的两个指令lpush和rpop或者rpush和lpop。
实现的时候可能遇到的技术难点:订单具有有效期,失效后自动删除并且恢复库存
本功能采用celery框架实现,下图是celery框架的基本架构。celery框架遵循生产者消费者模式,client生产任务通过进入broker提供的消息队列,worker从队列中取出任务进行处理运算。client和worker之间的消息传递通过broker,celery的broker依赖于前面提到的基于redis的消息队列。基于celery框架,我们可以关注于具体的任务逻辑。在celery配置文件中加入任务函数名和轮询间隔,在启动项目时启动celery,就可以实现根据轮询间隔自动调度任务。
基于celery框架,我们避免了手动定义定时器,用while(True)轮询数据库修改数据这种性能和鲁棒性极差的方式。我们采用了前面讲述的mongoDB事务实现失效订单删除逻辑,根据设置的轮询间隔扫描数据库删除过期订单
学号 191