前言
1、NewSQL TiDB数据库应用与实践
2、数据库数据无缝迁移方案设计
3、缓存数据一致性实践
4、深度解析Redis Cluster和Codis
NewSQL数据库应用与实践
NewSQL产品
Mysql+MongoDB
现状
亟待解决的问题
为何选择NewSQL
天然支持监控、Online DDL
TiDB特点
TiDB整体架构
架构图
1、TiDB计算层 做SQL解析 类比MongoDB的mongos
2、TiKV RocksDB是facebook开源的存储引擎
3、PD 类比MongoDB的config server
4、TiKV至少3个副本 至少有一个副本是不工作的 提供给TiSpark做计算
5、支持HTAP H是混合事务和交易型数据
访问逻辑
功能测试
性能测试
- TiDB Server节点服务器
16核开启超线程就是32核
- TiKv服务器
SSD盘
测试方案
测试结果
- 不同场景的QPS
在CPU 50%的情况下128个线程达到3万QPS是没有问题的
- 不同场景的响应时间
1、基本上在10几毫秒(95%的情况)
2、更新会慢一些 因为需要保证 3副本都写成功才返回
压力测试总结
使用场景建议
1、顺序写核读效率高些 随机写和读效率低些
2、适当的线程数少一些 响应时间、性能会提高一些
线程开64个线程就够了
预上线方案
线上业务接入步骤
测试验证
流程图
TiDB Proxy就是数据访问层
同步数据
流程图
切流量
流程图
部署结构图
1、LB即LBS
2、TiKv和TiDB都至少3台机器
3、TiDB和PD混用
4、至少6台机器 全都是物理机
线上监控
数据请求延时情况
Mysql波动很大
TiDb波动稳定
业务请求队列等待情况
Mysql抖动大
TiDB恒为1
业务延时和错误量情况
业务延时
接入TiDB后业务服务接口耗时稳定无抖动
错误量
数据访问层服务队列堆积Mysql发生请求丢弃
TiDB没有发生丢失情况
数据库数据无缝迁移方案设计
时效性数据
MongodDB数据迁移到Mysql
黑线表示从某一个时间点双写
比如优惠券数据时效性一个月
从1号开始双写 到下个月1号MongoDB数据失效
就需要关注MongoDB数据了
永久性数据
1、MongodDB和消息队列双写
2、MongoDB从库和主库脱离
3、MongoDB从库数据同步到Mysql
4、同步好之后 执行消息队列中的命令
5、在Mysql执行消息队列的命令时候 所有写请求写到内存中
6、消息队列中的消息消费完之后 去掉消息队列 将内存中的请求同步到Mysql
7、如果服务挂了 内存中缓存的请求丢失 用户会重试
缓存数据一致性实践
缓存数据即非持久化数据
缓存作用
- 降低请求的响应时间 提升用户体验
- 减少对固化存储(DB)的读压力
使用场景
适合场景
不适合场景
- 频繁更新
- 读少写多
缓存类别
本地缓存
Google Guava Cache
分布式缓存
使用场景
技术选型
Memcached特性
Redis特性
redis 持久化对性能影响很大
如何选择
Redis首选
单机容量比如192G内存
Redis Cluster
特点
分片逻辑在客户端
集群架构
Codis
特点
架构
1、codis-group即Redis集群 每一个group代表一主两从Redis(主从模式) 主从切换是哨兵模式
2、codis-proxy是go语言编写
3、proxy注册到zk中
后台管理功能
proxy
可以看到每秒请求情况
Slot情况
如上图
a、集群中有4个节点
b、每个节点存储所有槽点的1/4
c、codis最多分片1024个(槽点)
group
哨兵
深度解析
Redis Cluster
Redis Cluster深度分析
CAP分析
Redis Cluster属于AP模型
数据分布
Redis Cluster Master-Slave模式
节点 Node
分片Sharding
slot计算方式
CRC16(key)%16384
命令执行
- 槽位正确
- 槽位不正确
每个节点上都存了全量的映射关系
redis集群之间通过Gossip协议进行通讯
Gossip协议通讯
Redirection实现槽表(slot table)
故障转移(Failover)
环境搭建
Slot有多大 是否可以承载mget大小
slot迁移服务可用性
机器超时重试
Redis Master Slave作用
Redis Cluster fail over
Codis
环境搭建
稍显复杂 需要go、Zookeeper、proxy、redis
slot有多大 是否可以承载mget大小
mget的实现是在proxy层面做并行归并 已实现好
slot概念
节点挂了怎么办?
负载均衡
总结
分布式缓存高可用
思路一 高可用
多了一份缓存 数据不一致的概率就会增大
思路二 不高可用
缓存高可用意义不大
除非超大流量
缓存数据一致性
数据不一致的根源
多份数据存储 (数据库、缓存)
如何解决
时序控制是否可行
1、先更新数据库 再更新缓存
2、先更新缓存 再更新数据库
时序控制不可行 无法保证数据一致性
数据最终一致性保证
1、第一次删除失败则会
写到mq 延迟2秒钟
数据访问层订阅mq 再次删除缓存项
一旦第二次删除失败 会记录日志
通过脚本多次删除
(若过期时间1个小时 才最终一致性 时间太长)
2、写数据库不缓存 是因为写了不知道什么时候会读
所以读的时候才缓存 懒加载方式