编程技术框架
2021-07-18 17:57:33 56 举报
AI智能生成
个人编程框架
作者其他创作
大纲/内容
数据库-Mysql 存储引擎-innoDb
Mysql 存储引擎-innoDb
sql优化思路
DDL
索引的创建原则
三星原则
语句编写
只查询需要的字段、注意大字段的查询
注意命中索引,减少回表
order by 偏移量大
问题原因
1. 查询所有列导致回表
2. limit a, b会查询前a+b条数据,然后丢弃前a条数据
2. limit a, b会查询前a+b条数据,然后丢弃前a条数据
优化方案
减少回表(先定位主键值,再根据主键值定位行记录)
查询列少,建立联合索引(覆盖索引)
查询列少,建立联合索引(覆盖索引)
查询列多,先查询主键列,再根据查询结果join查询其他列
如果数据根据id自增 可以算出id设置where 条件,再limit
分布式数据库 order by limit
分片 query
限流
结果归并 再 order by limit
隔离级别,解决什么问题?
原理
可重复读是在事务开始的时候生成一个当前事务全局性的快照,
而读已提交则是每次执行语句的时候都重新生成一次快照
读未提交
没有加锁、没有隔离
脏读
不可重复读
在同一事务中,同样的条件,第一次读的数据和第二次读的「数据不一样」
幻读
在同一事务中,同样的条件,第一次和第二次读出来的「记录数不一样」
读已提交
每次执行语句的时候都重新生成一次快照
幻读
不可重复读
可重复读(mysqlinnoDB采用)
在事务开始的时候生成一个当前事务全局性的快照,
行锁和间隙锁合并在一起,解决了并发写和幻读的问题
部分防止幻读
串行读
读的时候加共享锁,也就是其他事务可以并发读,但是不能写。
写的时候加排它锁,其他事务不能并发写也不能并发读。
索引,B+树的特点
非叶子节点上是不存储数据的,仅存储键值,而 B 树节点中不仅存储键值,也会存储数据
B和B+树主要用在文件系统以及数据库做索引
MVVC
为了实现事务的隔离性,通过版本号,避免同一数据在不同事务间的竞争
MVCC只在READCOMMITTED和REPEATABLEREAD两个隔离级别下工作。其他两个隔离级别够和MVCC不兼容
实现机制
InnoDB在每行数据都增加三个隐藏字段,一个唯一行号,一个记录创建的版本号,一个记录回滚的版本号。
快照读是通过MVVC(多版本控制)和undolog来实现的,当前读是通过加recordlock(记录锁)和gaplock(间隙锁)来实现
bin log 、 undo log
doris
架构与部署
FE
FE 的磁盘空间主要用于存储元数据
FE 分为 Leader,Follower 和 Observer 三种角色
FE接收MySQL客户端的连接, 解析并执行SQL语句。
FE协调数据导入, 保证数据导入的一致性。
BE
BE 的磁盘空间主要用于存放用户数据
BE受FE指导, 创建或删除子表
BE接收FE分发的物理执行计划并指定BE coordinator节点,
在BE coordinator的调度下, 与其他BE worker共同协作完成执行。
在BE coordinator的调度下, 与其他BE worker共同协作完成执行。
BE读本地的列存储引擎获取数据,并通过索引和谓词下沉快速过滤数据。
coordinator节点 汇总处理结果 返回 FE
一台机器上可以部署多个 BE 实例,但是只能部署一个 FE
BROKER
从第三方存储系统导入数据,需要部署相应的 Broker
数据模型
AGGREGATE KEY
GGREGATE KEY相同时,新旧记录进行聚合,
目前支持的聚合函数有SUM, MIN, MAX, REPLACE。
AGGREGATE KEY模型可以提前聚合数据, 适合报表和多维分析业务
目前支持的聚合函数有SUM, MIN, MAX, REPLACE。
AGGREGATE KEY模型可以提前聚合数据, 适合报表和多维分析业务
只会存储聚合后的数据。即明细数据会丢失
UNIQUE KEY
UNIQUE KEY 相同时,新记录覆盖旧记录
适用于有更新需求的分析业务
DUPLICATE KEY
只指定排序列,相同的行不会合并。适用于数据无需提前聚合的分析业务。
Schema Change
查询流程
Analyze负责对AST进行前期的一些处理
SinglePlan根据AST进行优化生成单机查询计划
DistributedPlan将单机的查询计划拆成分布式的查询计划
Schedule阶段负责决定查询计划下发到哪些机器上执行
rollup 与 前缀索引
查询列与索引列顺序一致
建立rollup 表 命中索引
经典问题以及解决方案
幂等性处理
任意多次执行所产生的影响均与一次执行的影响相同
查询、删除 是天然的幂等操作
新增 : 唯一索引,避免重复新增
token 防止重复提交
分布式锁 防止并发操作
状态机管理
数据库记录版本管理,update 限制版本号
利用数据库的 事务隔离级别控制
利用数据库的 事务隔离级别控制
对外提供接口的api如何保证幂等
两个字段必须传,一个是来源source,一个是来源方序列号seq,
这个两个字段在提供方系统里面做联合唯一索引,
这样当第三方调用时,先在本方系统里面查询一下,
是否已经处理过,返回相应处理结果;没有处理过,进行相应处理
这个两个字段在提供方系统里面做联合唯一索引,
这样当第三方调用时,先在本方系统里面查询一下,
是否已经处理过,返回相应处理结果;没有处理过,进行相应处理
高并发下的缓存一致性
先更新数据库,再删除缓存
热点key的单机瓶颈,缓存击穿
主从架构->读写分离->水平扩容支撑高并发
优化hash规则,使请求分布均匀
优化热点key 的value大小,转移redis压力
多级缓存
设计模式
单例模式
管理固定对象,避免频繁建立、销毁,提高使用效率
双重检查,volitail 修饰固定对象,synchronized 代码块获取 对象
枚举方式(简单、安全),防止反射、反序列化
代理模式
代理类增强原类的方法
静态代理
实现相同接口,代理类在方法前后增加原类方法
动态代理
jdk动态代理
只能代理接口
代理类 需要实现 InvocationHandler 接口, 重写 invoke 方法
通过Proxy.newProxyInstance 生成代理类的实例,最终调用 invoke方法
cglib代理
字节码技术,动态生成 目标类的子类
不能代理 被 final 关键字修饰的类
实现 MethodInterceptor , 重写 intercept() 方法
通过 Enhancer 生成代理类的实例
工厂模式
装饰模式
数据结构、算法
链表的倒数第k个节点
Java基础
list
排序
实现 Comparable 接口
遍历删除元素
iterator
map
HashMap
put方法源码
key 的选择,最好是不可变对象,因为put的时候会对key 进行 hash
遍历hashmap
entrySet
LinkedHashMap
为什么有序?
重写HashMap的Node,增加了after和before字段,
遍历 entrySet 时 通过 双向链表来维护有序性
遍历 entrySet 时 通过 双向链表来维护有序性
5个构造方法,其中有4个的构造方法都是指定了accessOrder为false
accessOrder为false表示根据插入的顺序进行排序,
当为true的时候表示根据获取排序
accessOrder为false表示根据插入的顺序进行排序,
当为true的时候表示根据获取排序
图解LinkedHashMap原理
ConcurrentHashMap
减小锁粒度 + CAS
锁住头节点
volatile变量
泛型
list<?> 与 list<Object> 区别
List<?>:是一个泛型,在没有赋值前,表示可以接受任何类型的集合赋值,
但赋值之后不能往里面随便添加元素,但可以remove和clear
但赋值之后不能往里面随便添加元素,但可以remove和clear
List<Object> 可以接受任何类型的对象
泛型不可变,无继承关系
<T> T : 表示返回值类型不一定
T method(List<T> list) : 表示返回类型和传入类型一致
ThreadLocal
强应用、弱引用的区别
强引用 GC 不会回收 , 弱引用会被回收
Java进阶
并发
AQS、CAS
synchronized
Java 6 以前,所有的锁都是”重量级“锁
Java 6 及其以后,一个对象其实有四种锁状态,它们级别由低到高
Java 6 及其以后,一个对象其实有四种锁状态,它们级别由低到高
无锁状态
偏向锁状态
轻量级锁状态
重量级锁状态
偏向锁状态
轻量级锁状态
重量级锁状态
锁降级
锁降级发生在Stop The World期间,
当JVM进入安全点的时候,会检查是否有闲置的锁,然后进行降级
当JVM进入安全点的时候,会检查是否有闲置的锁,然后进行降级
锁升级
当对象状态为偏向锁时,Mark Word存储的是偏向的线程ID
轻量级锁时,Mark Word存储的是指向线程栈中Lock Record的指针
重量级锁时,Mark Word为指向堆中的monitor对象的指针。
一个对象的“锁”的信息是存放在 Java对象头
非数组对象 的对象头占 两个字节
数组对象 占3个字节
非数组对象 的对象头占 两个字节
数组对象 占3个字节
Mark Word 占一个字节 存储对象的hashCode或锁信息
Class Metadata Address 占一个字节 存储到对象类型数据的指针
Array length 占一个字节 数组的长度(如果是数组)
synchronize VS ReentrantLock
等待可中断
ReentrantLock 可以立即中断
不一定立即响应中断
公平锁
ReentrantLock 可以实现公平锁
锁的层面
ReentrantLock 是 API层面的锁 , 底层使用 CAS + 自旋
synchronized 是 JVM层面的 , 通过指令控制
使用多个条件
一个ReentrantLock对象可以同时绑定对个对象,实现多路准确通知
await、signal
synchronize
wait、notify
锁接口和类
可重入锁和非可重入锁
公平锁与非公平锁
读写锁和排它锁
ReentrantLock
”可重入“锁
支持”公平锁“和”非公平锁“。
排他锁
ReentrantReadWriteLock
还支持”读写锁“
StampedLock
读线程非常多而写线程非常少的场景下非常适用
线程池
原理
队列选择
阻塞队列的原理
丢弃策略
线程安全的类
同步容器
线程安全的原理
JVM
常见参数
JMM : java memory model
线程基础
线程的几种状态
new
runnable
blocked
waiting
time-waited
terminated
类加载
反射
双亲委派
1、沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
IO
两个阶段
等待数据准备 (Waiting for the data to be ready)
将数据从内核拷贝到进程中
四种常用模型
阻塞IO(BIO)
非阻塞IO 、 第一个阶段不是阻塞的,需要不断的主动问kernel数据好了没;第二阶段依然总体是阻塞的。
IO多路复用(NIO): 单个process就可以同时处理多个网络连接的IO
异步IO(AIO)
程序发起read操作之后,立刻就可以开始去做其它的事
kernel会等待数据准备完成,然后将数据拷贝到用户内存
一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了
中间件
缓存 redis
设计思路,架构图
跳表
链表加多级索引的结构,就是跳跃表
高可用
redis高可用:如果做主从架构部署,加上哨兵就可以了,任何一个实例宕机,自动会进行主备切换。
读写分离
用户和redis-proxy建立连接,redis-proxy会识别出客户端连接发送过来的请求是读还是写,
然后按照权重作负载均衡,将请求转发到后端不同的DB节点中,
写请求转发给master,读操作转发给read-only replica(master默认也提供读,可以通过权重控制)。
然后按照权重作负载均衡,将请求转发到后端不同的DB节点中,
写请求转发给master,读操作转发给read-only replica(master默认也提供读,可以通过权重控制)。
主从 + 哨兵
服务端分片, redis Cluster
- 采用16384个槽位进行路由规则的转发
- 在线数据迁移、节点扩容缩容
- 采用16384个槽位进行路由规则的转发
- 在线数据迁移、节点扩容缩容
持久化策略
RDB
AOF
缓存穿透
一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤
输入值的合法性校验
查询结果为空的情况也进行缓存,缓存时间设置短一点
缓存雪崩
- redis高可用, 集群
- 限流 、 降级
- 缓存预热,打散过期时间
- 多级缓存 、 应用内缓存
消息队列
怎么避免消息丢失? 服务宕机会发生什么
rocket mq
kafka
rocket mq
设计思路,架构图
NameServer
一个很简单的 Topic 路由注册中心,支持 Broker 的动态注册和发现,
保存 Topic 和 Borker 之间的关系。通常也是集群部署,
但是各 NameServer 之间不会互相通信, 各 NameServer 都有完整的路由信息,即无状态。
保存 Topic 和 Borker 之间的关系。通常也是集群部署,
但是各 NameServer 之间不会互相通信, 各 NameServer 都有完整的路由信息,即无状态。
Broker
主要负责消息的存储、查询消费,支持主从部署,
一个 Master 可以对应多个 Slave,
Master 支持读写,Slave 只支持读。
Broker 会向集群中的每一台 NameServer 注册自己的路由信息;
一个 Master 可以对应多个 Slave,
Master 支持读写,Slave 只支持读。
Broker 会向集群中的每一台 NameServer 注册自己的路由信息;
Producer
消息生产者,可以集群部署。
它会先和 NameServer 集群中的随机一台建立长连接,
得知当前要发送的 Topic 存在哪台 Broker Master上,
然后再与其建立长连接,
支持多种负载平衡模式发送消息;
它会先和 NameServer 集群中的随机一台建立长连接,
得知当前要发送的 Topic 存在哪台 Broker Master上,
然后再与其建立长连接,
支持多种负载平衡模式发送消息;
Consumer
消息消费者,也可以集群部署。
它也会先和 NameServer 集群中的随机一台建立长连接,
得知当前要消息的 Topic 存在哪台 Broker Master、Slave上,
然后它们建立长连接,支持集群消费和广播消费消息;
它也会先和 NameServer 集群中的随机一台建立长连接,
得知当前要消息的 Topic 存在哪台 Broker Master、Slave上,
然后它们建立长连接,支持集群消费和广播消费消息;
kafka
高可用
多个副本,保证数据安全
消息丢失的场景
没有到达确认 : 网络异常可能丢消息
异步发送:客户端批量发送,然后宕机
副本异常
acks设置为1时,Leader副本接收成功,Kafka集群就返回成功确认信息,
而Follower副本可能还在同步
而Follower副本可能还在同步
吞吐量 VS 消息完整性
允许丢失部分消息
异步+到达不确认
不丢失消息数据
同步 + 当Leader和Follower副本都接收成功后,返回接收成功确认信息
重复消费的场景
消费逻辑进行幂等性处理
高性能
数据文件分段存储
分布式:kafka是分布式部署的,能通过横向扩展提升读写效率
分区:通过分区的方式提升性能
日志编码:降低了消息的大小
消息压缩 、 批量处理
稀松索引 + 顺序写
提升消费者端读取 Offset 时访问物理存储的效率
用跳表思想,设计 Log 和 Index 文件
零拷贝技术,减少数据在不同环节的数据来回复制,
从而提升写入和读取的超快速度
从而提升写入和读取的超快速度
允许操作系统将数据直接从页缓存发送到网络上
避免从磁盘到内核到socket
注册中心
zookeeper
eureka
设计思路,架构图
Java框架
spring
IOC : 源码阅读
bean的生命周期
三层依赖
事务
隔离级别
传播等级
默认配置
springboot
启动流程
收藏
0 条评论
下一页