MySQL分库分表
分库分表系统正在持续不断地发展,注册的用户越来越多,数据库中存储的数据也越来越多。
会遇到的问题:
这时即使你使用了索引,索引占用的空间也随着数据量的增长而增大,数据库就无法缓存全量的索引信息,那么就需要从磁盘上读取索引数据,就会影响到查询的性能了。
数据量的增加也占据了磁盘的空间,数据库在备份和恢复的时间变长。
不同模块的数据,比如用户数据和用户关系数据,全都存储在一个主库中,一旦主库发生故障,所有的模块都会受到影响。
这些问题都是数据库的写入请求量大造成的性能和可用性方面的问题,一般采取的措施就是对数据进行分片即分库分表。
为什么要分库分表:
如果数据库已经到了写瓶颈怎么办?要么优化写操作,要么分库。
对于写瓶颈来说,分区表可以缓解问题,而读写分离几乎没有效果,比如频繁地增删改操作。
如果数据库已经到了读瓶颈怎么办?要么优化读操作,要么加从库,要么分库或分表。
对于硬件瓶颈来说,读写分离、分区表基本上也解决不了,比如写操作引发的网络带宽问题。
一般非必要不进行分库分表,大致要求如下:
单表数据超过1000w
单表数据文件大小超过20GB
方案分为:
单库多表:有 ...
MySQL读写分离
主从读写分离大部分系统的访问模型是读多写少,读写请求量的差距可能达到几个数量级。
因此,我们优先考虑数据库如何抵抗更高的查询请求,那么首先你需要把读写流量区分开,因为这样才方便针对读流量做单独的扩展(但是不易太对IO线程消耗太大,一般一个主库最多挂 3~5 个从库),这就是我们所说的主从读写分离。从库也可以当成一个备库来使用,以避免主库故障导致数据丢失。
主从读写分离有两个技术关键点:
一个是数据的拷贝,我们称为主从复制;
在主从分离的情况下,我们如何屏蔽主从分离带来的访问数据库方式的变化,让开发像是在使用单一数据库一样。
主从复制以MySQL的主从复制为例,MySQL 的主从复制是依赖于 binlog 的,主从复制就是将 binlog 中的数据从主库传输到从库上,一般这个过程是异步的,即主库上的操作不会等待 binlog 同步的完成。
同步完整流程:
一个事务日志同步的完整过程是这样的:
在备库B上通过change master命令,设置主库A的IP、端口、用户名、密码,以及要从哪个位置开始请求binlog,这个位置包含文件名和日志偏移量。
在备库B上执行start s ...
池化技术
池化技术数据库连接池数据库的调用方式是先获取数据库的连接,然后依靠这条连接从数据库中查询数据,最后关闭连接释放数据库资源。这种调用方式下,每次执行 SQL 都需要重新建立连接,频繁地建立数据库连接是很耗费时间的。
这个时候就需要用到池化技术:建立数据库连接池。
数据库连接池有两个最重要的配置:最小连接数和最大连接数
最小连接数:是连接池一直保持的数据库连接
最大连接数:是连接池能申请的最大连接数
从连接池中获取连接的相关策略:
如果当前连接数小于最小连接数,则创建新的连接处理数据库请求,保证池中的最小连接数;
如果当前连接数大于最小连接数小于最大连接数
如果连接池中有空闲连接则复用空闲连接;
没有则创建新的连接处理请求;
如果当前连接数已经大于等于最大连接数,则按照配置中设定的时间(C3P0 的连接池配置是 checkoutTimeout)等待旧的连接可用
如果等待超过了这个设定时间则向用户抛出错误。
会遇到的问题:连接断开问题:
数据库的域名对应的 IP 发生了变更,池子的连接还是使用旧的 IP。
MySQL 有个参数是“wait_timeout”,控制着当数据库连接 ...
MockMvc
MockMvcMockMvc是由spring-test包提供,实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,使得测试速度快、不依赖网络环境。同时提供了一套验证的工具,结果的验证十分方便。
开发步骤:
接口:
1234567@GetMapping ("/logger")@ResponseBodypublic string testLogger () { Logger logger = LoggerFactory.getLogger(this.getClass()) logger.debug ("测试级别日志"); return "SUCCESS"; }
在test包下创建一个测试类:
1234567891011121314151617181920212223242526272829303132333435363738@SpringBootTest(classes = {SpringbootApplication.class },w ...
开源协议
开源协议概述开源协议是规定软件源代码如何被使用、修改和分发的法律文本。这些协议为开发者提供了在保持源代码开放的同时,规定了一些使用条件和责任。以下是一些常见的开源协议:
主流协议
GNU通用公共许可证(GNU General Public License,GPL):
特点:软件的使用是免费的,强调用户有权查看、修改和重新分发源代码。如果您修改了代码并重新分发,您的修改必须也是开源的。
版本:GPL有不同的版本,包括GPLv2和GPLv3。
场景:适用于二次或N次开发,那么发布时要带上源码,让其传播,所以它最终的版权是大众的,而非某一个人的,因此不用交钱就可以使用。
MIT许可证:
特点:目前限制最少的开源许可协议之一(比BSD和Apache的限制都少),只要程序的开发者在修改后的源代码中保留原作者的许可信息即可,简单且自由度较高。允许在源代码中包含此许可证,允许任何人免费使用、修改和分发您的代码,只需保留原始许可证和版权声明。
场景:普遍被商业软件所使用。
Apache许可证:
特点:Apache协议具体为许可证版本(Apache License Version)协议,Ap ...
数据迁移细节
数据迁移细节数据迁移运用场景:
重构项目但数据不能丢失,需要重新设计表结构
单库拆分分库分表
数据备份工具
mysqldump:一个用于备份和恢复 MySQL 数据库的命令行工具。它允许用户导出 MySQL 数据库的结构、数据以及表之间的关系,以便在数据库发生问题时进行恢复。它是一个逻辑备份工具,导出的内容是一条条 SQL。
XtraBackup:它使用了 InnoDB 存储引擎的数据备份技术,支持增量备份和恢复,并且支持多主机备份和恢复。它是一个物理备份工具,相当于直接复制 InnoDB 的底层存储文件。
innodb_autoinc_lock_mode 是 InnoDB 引擎里面控制自增主键生成策略的参数,它有三个取值。
0:使用表自增锁,但是锁在 INSERT 语句结束之后就释放了。
1:使用表自增锁,如果是普通的 INSERT INTO VALUE 或者 INSERT INTO VALUES 语句,申请了主键就释放锁,而不是整个 INSERT 语句执行完毕才释放。如果是 INSERT SELECT 等语句,因为无法确定究竟要插入多少行,所以都是整个 INSERT 语 ...
高并发系统设计目标
系统设计目标高并发系统设计的三大目标:高性能、高可用、可扩展。
高性能:保证系统能够承载高并发的前提。
高可用:防止系统隔三差五宕机维护停机。
可扩展:保证能够在短时间内迅速完成扩容,更加平稳地承担峰值流量。
提升系统性能性能优化原则
性能优化一定不能盲目,一定是问题导向的。
脱离了问题,盲目地提早优化会增加系统的复杂度,浪费开发人员的时间,也因为某些优化可能会对业务上有些折中的考虑,所以也会损伤业务。
性能优化也遵循“八二原则”。
在优化过程中一定要抓住主要矛盾,优先优化主要的性能瓶颈点。
性能优化也要有数据支撑。
一定要把性能监控系统做好,在优化过程中,时刻关注优化效果。
性能优化的过程是持续的。
高并发的系统通常是业务逻辑相对复杂的系统,在优化过程中需要循序渐进,不断寻找性能瓶颈并优化。
性能的度量指标性能的度量指标主要用于明确性能问题、评估优化效果。
度量性能的指标是系统接口的响应时间,但是单次的响应时间是没有意义的,需要知道一段时间的性能情况是什么样的,主要的统计特征值有:
平均值
平均值是把这段时间所有请求的响应时间数据相加,再除以总请求数。但是不能真实反应 ...
架构分层
架构分层软件架构分层在软件工程中是一种常见的设计方式,它是将整体系统拆分成 N 个层次,每个层次有独立的职责,多个层次协同提供完整的功能。
常见分层架构MVC(Model-View-Controller)架构
它将整体的系统分成了 Model(模型),View(视图)和 Controller(控制器)三个层次,也就是将用户视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是一种标准的软件分层架构。
另外一种常见的分层方式是将整体架构分为表现层、逻辑层和数据访问层:
表现层,顾名思义嘛,就是展示数据结果和接受用户指令的,是最靠近用户的一层;
逻辑层里面有复杂业务的具体实现;
数据访问层则是主要处理和存储之间的交互。
计网中的 TCP/IP四层模型:
分为链路层、网络层、传输层和应用层
每一层各司其职又互相帮助,网络层负责端到端的寻址和建立连接,传输层负责端到端的数据传输等,同时相邻两层还会有数据的交互。这样可以隔离关注点,让不同的层专注做不同的事情。
分层的优缺点优点:
首先分层的设计简化了系统设计,让人各司其职只关注某一层的事情。
再次就是提高了 ...
高并发系统通用设计方法
高并发系统通用设计方法概述在应对高并发大流量时主要有三种方法:
Scale-out(横向扩展):分而治之是一种常见的高并发系统设计方法,采用分布式部署的方式把流量分流开,让每个服务器都承担一部分并发和流量。
缓存:使用缓存来提高系统的性能,就好比用“拓宽河道”的方式抵抗高并发大流量的冲击。
异步:在某些场景下,未处理完成之前我们可以让请求先返回,在数据准备好之后再通知请求方,这样可以在单位时间内处理更多的请求。
Scale-out(横向扩展)这个方案的思想来源于CPU的发展,从单CPU到多核CPU;由于单CPU的工艺无法再有所突破,则将多个 CPU 核心压在一个芯片上,从而大大提升 CPU 的并行处理能力。其中单CPU的性能突破叫做Scale-up(纵向扩展),多核心的思想叫做Scale-out(横向扩展)。
Scale-up(纵向扩展):
通过不断提高单体性能的思想,比如升级单台服务器硬件。这种方案简单方便。
Scale-out(横向扩展):
通过将多个低性能的机器组成一个分布式集群来共同抵御高并发流量的冲击。但是引入了多节点管理的问题。
缓存缓存的思想遍布系统设计的每个 ...
经典限流算法
经典限流算法前述限流算法是一种用于控制流量或请求访问频率的技术,广泛应用于各种场景,以确保系统的稳定性和可用性。
现代互联网很多业务场景,比如秒杀、下单、查询商品详情。这些只是一些限流算法应用的示例,实际上,几乎任何需要控制流量或请求速率的应用都可以从限流算法中受益。选择适当的限流算法取决于具体的需求和系统架构。常见的限流算法包括令牌桶算法、漏桶算法、计数器算法等。
算法详解计数器算法计数器算法是一种基于计数器的限流方法。它通过维护一个计数器来记录请求的数量,并与预设的阈值进行比较。
当计数器超过阈值时,就会触发限流操作。可以根据需要选择计数器的精度(例如每秒、每分钟等)以及阈值的设置。
缺点:
临界问题:例如在临界两把突发的高峰,无法进行限制。
滑动窗口算法滑动窗口,又称rolling window。滑动窗口算法维护一个固定大小的时间窗口,通常使用队列或数组来记录请求的时间戳。
请求进入窗口时,旧的时间戳会被移出,从而保持窗口内的请求数量在限制范围内。
滑动窗口解决了计数器算法的临界值问题。
缺点:
不适用于长时间限流:滑动窗口算法通常用于实时或较短时间的限流,例如每秒 ...