数据库基础架构
数据库的锁
1.乐观锁
2.悲观锁
3.行级锁(InnoDB)
- 共享锁
- 排它锁
4.表级锁(MyISAM) - 表共享读锁
- 表独占写锁
5.页级锁(BDB)
基础锁的知识
- 对于update, delete, insert 语句在执行的时候, InnDB会自动给涉及的数据集合加上排他锁
- MyISAM 在执行查询语句select 前,会自动给涉及的所有表加上读锁, 在执行update, delete, insert 前会自动加上写锁,这个过程不需要用户干预
表锁
- 开销小,加锁快,不会出现死锁,锁定力度大, 发生锁冲突概率高, 并发差
行锁
- 开销大,加锁慢, 会出现死锁, 发生锁冲突概率低, 并发好
- 共享锁:也叫读锁,多个用户读取同一个资源,但是不允许其他客户修改,允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁
- 排他锁:也叫写锁, 写锁是排他的,会阻塞其他的写锁和读锁
InnoDB只支持行锁和表锁, 只有通过检索条件检索数据的时候采用到行级锁,其次则用表锁
MyISAM只支持表锁
乐观锁
乐观锁并未真正加锁,而是在最后提交的时候进行冲突检测
乐观锁的概念中其实已经阐述了他的具体实现细节:主要就是两个步骤:冲突检测和数据更新。其实现方式有一种比较典型的就是Compare and Swap(CAS)技术
悲观锁
select * from xxxx for update
在select 语句后边加了 for update相当于加了排它锁(写锁),加了写锁以后,其他的事务就不能对它修改了!需要等待当前事务修改完之后才可以修改.
MySQL InnoDB默认行级锁。行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住,这点需要注意。
乐观锁和悲观锁比较
在乐观锁与悲观锁的选择上面,主要看下两者的区别以及适用场景就可以了。
1、乐观锁并未真正加锁,效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。
2、悲观锁依赖数据库锁,效率低。更新失败的概率比较低。
随着互联网三高架构(高并发、高性能、高可用)的提出,悲观锁已经越来越少的被使用到生产环境中了,尤其是并发量比较大的业务场景。
MyISAM
1.不支持事务
2.插入和查询速度更快
3.适合仅用作数据仓库只使用查询的需求的数据库
数据库高并发架构
数据库分表
- 1.解决存储问题:将同一张表放到不同的服务器上,进行数据层面的划分,减少单台服务器的压力
- 1.1.出现的问题:
- 数据库id, 例如50在每一个分表都出现了,但是我们在查询的时候无法确定
- 使用SnowFlake
- SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。
- 第一个部分,是 1 个 bit:0,这个是无意义的。
- 第二个部分是 41 个 bit:表示的是时间戳。
- 第三个部分是 5 个 bit:表示的是机房 id,10001。
- 第四个部分是 5 个 bit:表示的是机器 id,1 1001。
- 第五个部分是 12 个 bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的 id 的序号,0000 00000000。
- 2.解决并发读取延迟问题: 读写分离,创建数据库主从结构
- 就是写的时候写入主数据库服务器,主数据库会自动同步到从数据库中
- 读的时候在从数据库中查询
- 3.数据库架构设计
- 注意设计并发是数据冲突
- 可以巧妙使用锁或者唯一约束
- 写入数据库的时候可以借助redis持续写入,不要直接向数据库发送请求
- 多使用redis 作为中间的消息队列
- 4.解决瞬间爆炸的查询如定时抢红包
- 我们使用消息队列存储参与用户的信息,再写一个多线程程序去消耗队列
主从数据库同步原理
- 1.主库将数据写到一个二进制文件中
- 2.然后从数据库开启线程读取这个二进制文件
- 3.然后从数据库将读到的数据存到relay 中继文件中(设置中继文件的原因是提高性能, 将文件中得到多条数据一次写到从数据库中, 避免频繁读写)
- 4.从数据开一个线程将中继文件的数据写到数据库中
负载均衡
Nginx
- 加权轮询
- IP哈希
- 最少连接数
- 一致性哈希