高并发下的系统设计(偏数据库设计)

高并发完毕数据库设计是要结合不同的应用场景的,本文主要涉及到一下问题:

1、对数据库表的字段訪问比較均衡,业务导向明显(网上商城,多条业务线);

2、对数据库表的字段訪问比較均衡,业务导向不明显(对单一应用的高并发訪问);

3、对数据库表的单一字段訪问比較集中(秒杀、大量用户对同一账户操作)

只是对于一般的小型站点的应用,并发高的话 採用读写分离基本上就能解决这个问题,本文主要是针对大型站点高并发数据库设计讨论。

一、对数据库表的訪问比較均衡,业务导向明显(网上商城,多条业务线)

像这样的情况,一般採用数据库表垂直切分。

垂直切分就是要把表按模块划分到不同数据库中,这样的拆分在大型站点的演变过程中是非经常见的。当一个站点还在非常小的时候,仅仅有小量的人来开发和维护。各模块和表都在一起,当站点不断丰富和壮大的时候。也会变成多个子系统来支撑,这时就有按模块和功能把表划分出来的需求。例如以下图所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ2tlaHVhaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

事实上,相对于垂直切分更进一步的是服务化改造。说得简单就是要把原来强耦合的系统拆分成多个弱耦合的服务,通过服务间的调用来满足业务需求看,因此表拆出来后要通过服务的形式暴露出去,而不是直接调用不同模块的表,淘宝在架构不断演变过程。最重要的一环就是服务化改造,把用户、交易、店铺、宝贝这些核心的概念抽取成独立的服务,也很有利于进行局部的优化和治理。保障核心模块的稳定性。这样一种拆分方式也是有代价的:

  • 表关联无法在数据库层面做
  • 单表大数据量依旧存在性能瓶颈
  • 事务保证比較复杂
  • 应用端的复杂性添加

上面这些问题是显而易见的,处理这些的关键在于怎样解除不同模块间的耦合性,这说是技术问题。事实上更是业务的设计问题,仅仅有在业务上是松耦合的,才可能在技术设计上隔离开来。

没有耦合性,也就不存在表关联和事务的需求。

另外,大数据瓶颈问题能够採用水平切分。

二、对数据库表的字段訪问比較均衡,业务导向不明显(对单一应用的高并发訪问)

1)这样的情况一般採用对数据库表进行水平切分。

上面谈到垂直切分仅仅是把表按模块划分到不同数据库,但没有解决单表大数据量的问题,而水平切分就是要把一个表依照某种规则把数据划分到不同表或数据库里。比如像计费系统。通过按时间来划分表就比較合适。由于系统都是处理某一时间段的数据。而像SaaS应用。通过按用户维度来划分数据比較合适,由于用户与用户之间的隔离的,一般不存在处理多个用户数据的情况,以下是一个比較简单的按user_id来水平切分的样例:

水平切分没有破坏表之间的联系,全然能够把有关系的表放在一个库里。这样就不影响应用端的业务需求,而且这种切分能从根本上解决大数据量的问题。它的问题也是非常明显的:

  • 当切分规则复杂时,添加了应用端调用的难度
  • 数据维护难度比較大,当拆分规则有变化时,须要对数据进行迁移

对于第一个问题,能够參考怎样整合应用端和数据库端。

对于第二个问题能够參考一致性hash的算法,通过某些映射策略来减少数据维护的成本

2)当然还能够把水平切分和垂直切分结合起来

由上面可知垂直切分能更清晰化模块划分,区分治理,水平切分能解决大数据量性能瓶颈问题。因此经常就会把两者结合使用,这在大型站点里是种常见的策略。这能够结合两者的长处,当然缺点就是比較复杂,成本较高,不太适合小型站点,以下是结合前面两个样例的情况:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ2tlaHVhaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >

三、对数据库表的单一字段訪问比較集中(秒杀、大量用户对同一账户操作)

对于这样的情况有非常多种解决方式。可是每一种都不是非常完美:

1)採用内存缓存或者缓存数据库来缓解数据的库的压力

详细做法是:在利用内存缓存或者缓存数据库把后台数据库server上相关的表数据载入到内存中,所用用户高并发的对内存数据进行处理,然后再定时轮询的方式把内存的数据刷新到后台数据库表中,这样的做法有下面问题:

a)不能非常好保持内存数据与数据库数据的一致性。

b)假设出现断电、内存损坏等情况,会有数据丢失;

2)採用对数据库表水平切分。然后在后台的程序中对各个表的数据总体控制

比如,有10000亿人民币为1亿人并发提供贷款业务。

在数据库中建立一个总表存下10000亿人民币,然后再建立10张分表。初始设为空;后台java程序在訪问数据库时会有一个控制程序(中间件),开10个 线程池。每一个线程池相应一个数据库分表,其中间件接受到贷款申请时,中间件就会依据用户的ID(能够ip地址,账户编号)hash到相应的线程去到总表中借款,这个借款数目能够依据总表的资金和用户的要借的资金去申请额度(比方用户申请10w,总表有1000亿,相应线程能够向总表申请10亿),存入相应分表。供这个用户提供贷款,假设再有下个用户再到此线程池操作数据库表,就直接操作。分表中金额不够的时候再到总表中借款。

这种设计攻克了,高并发存储数据库的问题,可是添加了后台的程序设计的难度,加大了程序的耦合度。

3)採用“记流水不记账“的方式应对

还用上一个样例,这样的方式。须要在数据库中设计两个表,一个用来存储账户金额(账户表),还有一个记录”流水“(流水表), 所谓”记流水“是指每当有个请求到来,就向流水表中插入一条记录。然后定时对所插入的记录进行统计,update账户表的数据,当然这样的方式,须要在内存中添加变量,来控制所用用户的贷款不能超过所贷款的总金额。这样的处理方式是数据库端处理秒杀、高并发集中訪问数据库表字段的有效方式,使用比較广泛。

4)针对网购秒杀还有其针对性的设计。由于网购秒杀和高并发操作银行账户不同,网购秒杀同意用户请求丢失,简单的来说,仅仅须要在内存缓存或者内存数据库(充当队列)中保存较早的用户请求。然后再异步的处理这些请求来操作数据库(更新数据库)。

时间: 2024-10-14 06:41:38

高并发下的系统设计(偏数据库设计)的相关文章

高并发,大容量,高性能数据库设计优化

1.数据存储 a.集中式---->分布式 复制m/s.切分 a.1切分 垂直切分(按功能模块) 难点:跨域的表关联--->应用程序 事务---------->分布式的事务(单独数据源的小事务,然后通过程序控制) 某些表访问剧增----->读写分离 读写分离(异构数据源之间的读写分离) 相同数据源,只需要master/slave 难点:异构数据源之间的全量复制问题 异构数据源之间的增量同步问题(解析日志) 水平切分(按记录切分---->找规则) a.2 数据切分及整合的中间件

通用用户权限系统设计(数据库设计)

做了n多的MIS系统,很久以前就有这种想法,想把MIS系统中的用户权限 管理和审批流管理独立出来,做成单独的组件 今天暂时就看权限管理系统的数据库表设计吧. 子系统表,因为我这里设计的为了能够集成公司内部以后所有的系统的,所以建了子系统这张表,如果单个项目,这张表可以去掉.模块表,系统中的各个模块.模块功能表,模块中的各个功能(可以有两种功能,一种是页面的进入权限,一种是页面上的按钮事件)用户表角色表用户分组表用户部门表用户权限表(也可以直接对用户赋予权限)角色权限表(对角色赋予权限)用户和分组

评论系统数据库设计及实现

评论系统数据库设计及实现 需求分析 一般我们浏览网站的时候经常能看到如下图的这种效果(图片来自CSDN) 这种评论层层嵌套,每个评论下面还挂着若干个对评论的回复. 这种结构类似于树状结构,用户看起来一目了然,也是一种非常主流的评论系统设计. 数据库设计 在以评论为主的树形结构中,数据库的设计非常灵活,可以是单表设计,每个评论都有一个parent_id指向父评论.还可以分开为两个表,评论一张表,对评论的回复是另一张表. 这里我使用的是单表设计. 数据表设计如下.由于我开发的是一个新闻系统,所以我就

15套java互联网架构师、高并发、集群、负载均衡、高可用、数据库设计、缓存、性能优化、大型分布式 项目实战视频教程

* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 视频课程包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat

面试实战考核:设计一个高并发下的下单功能

功能需求:设计一个秒杀系统 初始方案 商品表设计:热销商品提供给用户秒杀,有初始库存. @Entity public class SecKillGoods implements Serializable{ @Id private String id; /** * 剩余库存 */ private Integer remainNum; /** * 秒杀商品名称 */ private String goodsName; } 秒杀订单表设计:记录秒杀成功的订单情况 @Entity public clas

36套精品Java高级课,架构课,java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,第三方支付,web安全,高并发,高性能,高可用,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,大型分布式电商项目实战视频教程

新年伊始,学习要趁早,点滴记录,学习就是进步! QQ:1225462853 视频课程包含: 36套Java精品高级课架构课包含:java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,架构设计,web安全,高并发,高性能,高可用,高可扩展,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,工作流,程序调优,负载均衡,Solr集群与应用,主从复制,中间件,全文检索,Spring boot,Spring cloud,Dubbo,Elasticsearch,Redis,ActiveMQ

高并发的下的数据库设计

现在都什么年代了,还拿着sql server mysql oracle 读取数据呢,好你们遇到的问题我来给你们解答下 在高并发情况下,谈谈数据库与Redis之间如何进行数据同步(写,读),即能保证业务的完整性,又能提升性能 方式1:数据库保存数据,redis不persistredis启动后,从数据库加载数据不要求强一致实时性的读请求,都由redis处理要求强一致实时性的读请求,由数据库处理写请求有2种处理方式,由数据库处理- 应用先写道数据库,然后更新redis- 应用先写道数据库,然后其它da

Java精品高级课,架构课,java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,第三方支付,web安全,视频教程

36套精品Java架构师,高并发,高性能,高可用,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,P2P金融项目,大型分布式电商实战视频教程 视频课程包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Elasticsearch,Redis.ActiveMQ.Nginx.Mycat.Spring.MongoDB.ZeroMQ.Git.Nosql.Jvm.Mecached.Netty.Nio.Mina.java8新特性,P2P金融项目,程序设计,

数据库设计中的一些原则

1. 原始单据与实体之间的关系 可以是一对一.一对多.多对多的关系.在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体. 在特殊情况下,它们可能是一对多或多对一的关系,即一张原始单证对应多个实体,或多张原始单证对应一个实体. 这里的实体可以理解为基本表.明确这种对应关系后,对我们设计录入界面大有好处. [例1]:一份员工履历资料,在人力资源信息系统中,就对应三个基本表:员工基本情况表.社会关系表.工作简历表.   这就是"一张原始单证对应多个实体"的典型例子. 2.