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