海量用户如何分库分表
4.1: 分库两种模式:
- 垂直分库:电商数据库拆分为用户、订单、商品、交易等数据库。
- 水平分库:用户数据库,拆分为多个,比如User_DB_0 - x。
4.2: 分表两种模式:
- 垂直分表:将数据库表按照业务维度进行拆分,将不常用的信息放到一个扩展表。
- 水平分表:将用户表水平拆分,展现形式就是 User_Table_0 - x。
4.3: 什么场景下分库分表?
1. 什么场景下分表?
数据量过大(b+数层级变高)或者数据库表对应的磁盘文件过大(数据库备份文件太大,磁盘文件过大在备份的时候会很慢的)。
Q:多少数据分表?
取决于一个表中有多少字段,以及有没有text字段,如果有text字段直接放在扩展表中。
数据的增长量如果很快,要进行分表
2. 什么情况下分库?
连接不够用。
一个mysql数据库可以同时处理多个数据请求(可以同时建立多个数据库连接),假设MySQL Server 支持 4000 个数据库连接。一个服务连接池最大 10 个,假设有 40 个服务节点。已经占用了 400 个数据库连接。
类似于这种服务,有10个,那你这个 MySQL Server 连接就不够了。
3. 又分库又分表?
高并发写入或查询场景。
数据量巨大场景。单一的数据库存储量太大,环节数据库存储压力
4.4:数据库分库分表框架 ShardingSphere
Sharding-JDBC。
4.5:代码实现:
将用户表分成了16个表。
application.yaml
server:
port: 8002
spring:
application:
name: short-link-admin
#在数据源这一栏直接用shardingsphere的来替换我们之前的jdbc数据源
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
url: jdbc:shardingsphere:classpath:shardingsphere-config-${database.env:dev}.yaml
data:
redis:
host: localhost
port: 6379
password: 171612cgj
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
short-link:
group:
max-num: 20
flow-limit:
enable: true
time-window: 1
max-access-count: 20
shardingsphere-config-dev.yaml
dataSources:
ds_0:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource #指定数据源 HikariCP连接池,这是一个高性能的 JDBC 连接池
driverClassName: com.mysql.cj.jdbc.Driver # 指定jabc驱动
jdbcUrl: jdbc:mysql://127.0.0.1:3306/link?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai #指定数据库位置以及一些参数
username: root #数据库连接的用户名与密码
password: 171612Cgj.
rules: # 这部分配置了两个主要的功能:数据分片和数据加密。
- !SHARDING # 数据分片
tables:
t_user:
actualDataNodes: ds_0.t_user_${0..15} #数据实际存储节点: user_0 -> user_15 这16个表 存储在ds_0这个库下
tableStrategy: #定义表的分片策略
standard:
shardingColumn: username #分片依据的字段
shardingAlgorithmName: user_table_hash_mod #分片算法
t_group:
actualDataNodes: ds_0.t_group_${0..15}
tableStrategy:
standard:
shardingColumn: username
shardingAlgorithmName: group_table_hash_mod
shardingAlgorithms: # 具体的分片算法
user_table_hash_mod:
type: HASH_MOD #具体的分片算法是:HASH_MOD
props:
sharding-count: 16 #分片数量 数据将根据分片算法被分散到 16 个不同的分表中
group_table_hash_mod:
type: HASH_MOD
props:
sharding-count: 16
- !ENCRYPT #数据加密
tables:
t_user:
columns: #需要加密的字段 t_user表中的phone字段和mail字段
phone:
cipherColumn: phone # 加密后存储的字段名这里直接用原列名表示加密覆盖原数据。
encryptorName: common_encryptor # 使用的加密器名称。
mail:
cipherColumn: mail
encryptorName: common_encryptor
queryWithCipherColumn: true #是否在查询时使用加密列。
encryptors:
common_encryptor:
type: AES # 使用的加密算法是AES加密算法
props:
aes-key-value: d6oadClrrb9A3GWo # 这是 AES 加密算法使用的密钥
props:
sql-show: true #ShardingSphere 会在日志中显示实际执行的 SQL 语句以及逻辑sql