存储
2021-03-03 10:54:21 0 举报
AI智能生成
登录查看完整内容
java面试_存储
作者其他创作
大纲/内容
存储
mysql
sql执行过程
1、连接: TCP/IP 如果是查询,会考虑是否查询缓存,但是不好用,因为只要更新了表数据,缓存里的数据都会失效;一般配置表可以考虑2、分析: 语法树3、优化: 决定使用哪个索引,生成执行计划,4、执行:=======5、undolog:6、搜索:7、redo_log: prepare阶段8、bin_log:二进制;binlog记录修改数据的sql;数据恢复和主从复制9、提交事务:让redolog和bin_log保持一致
内存模型
三大链表
free链表
由来:记录哪些区域是空闲的,这样缓存的时候,直接找到位置存储
flush链表
由来:更新数据之后,内存中的数据被改掉,那同步磁盘线程 同步数据需要知道哪些被修改了(脏页),因此,需要有一个链表记录哪些数据被修改了
lru链表
由来:bufferPool进行缓存,如果内存不够了,需要进行清理缓存,哪些缓存可以清理,lru链表记录
组成:热数据区域(5/8)+冷数据区域(3/8),中间的点叫midpoint
运作方式:数据页进入bufferPool中,首先进入冷数据区域的头部;如果再次被访问,则判断,两次访问时间间隔,如果超过1秒,则进入热数据区域头部
为什么是1秒:就是说,加入缓存的数据页扫描的时候,一行一行的扫描,时间不会超过1秒
理由:1、防止全表扫描导致缓存数据被大量清理2、数据预读页(预读机制)可能不是热点数据,如果不会被再次访问,慢慢的就会被清理
关系:可以简单记为,free链表和lru链表互补,free链表存的是空闲的内存,lru链表存的是被占用的内存
三大log
undo_log
innodb专属日志
用于事务回滚
redo_log
innodb专属日志:主要作用是进行数据落盘,后台专门有一个线程扫描这个redolog
redo_log保证在数据库崩溃宕机恢复之后,可以利用redo_log,保证已经提交的事务会数据落盘
数据怎么落盘呢先将数据页加载到内存,然后执行事务,
bin_log
mysqlserver层日志
redo_log记录的是X数据页X行做了X改动,而且日志是循环记录,已经commit的日志会慢慢被丢弃,无法用于大型的数据恢复bin_log则记录全部的数据修改日志,可以用于数据大型的数据恢复可用于主从复制
索引(innodb)
理解:
mysql中的索引实际上是一个数据结构;mysql中的不同的存储引擎的索引是不一样的,比如memory存储引擎的数据结构是hash表,innodb和myisam的数据结构是b+树;innodb选用b+树的原因是最大限度的减少树的高度,从而减少io次数,提高查询速率;mysql有各种索引,比如主键索引、组合索引、普通索引、唯一索引等。工作中,用的比较多的是主键索引和组合索引,在使用这些索引的时候,我们要注意回表、索引下沉、最左匹配、索引覆盖等问题;综上,索引是一种数据结构,帮助我们提高查询数据的速度
索引覆盖:我们要查的字段通过非主键索引已经能够获取,不再需要回表的操作
分类
主键索引
主键索引就是唯一索引+不能为空
如果没有主键索引会出现什么问题1、行锁失效;行锁锁的是主键索引,没有主键,会造成行锁变表锁;2、如果一个字段声明了自增,声明了主键,却没有声明主键索引,达到int上限后会从0开始覆盖;如果声明了主键索引,则会报主键冲突;3、系统会默认的创建rowId,6Byte;
唯一索引
值不允许重复
普通索引
组合索引
全文索引
结构
b+树
其他树为什么不行
搜索二叉树:退化成链表平衡二叉树:要求严格,左右子树的高度相差不能超过1红黑树:高度不行
原则
事务
事务四大特性
原子性(A)
一致性性(C)
隔离性(I)
隔离性导致的问题/三大并发问题
脏读
读到别的事务未提交的数据
不可重复读
我重复读的时候,两次数据不一致
幻读
两次count的数据不一致
隔离级别
读未提交
读已提交
可重复读
串行化
持久性(D)
lbcc基于锁的并发控制
共享锁(又叫读锁,属于行锁):select的时候,lock in share mode;表示在读的时候,该资源会被锁住,不允许被修改,只有该行的所有读锁被释放了,才可以修改
加锁:select * from t1 where id = 1 lock in share mode;
排他锁(,属于行锁):加上排锁锁之后,自己可以对资源进行增删改查,其他事务不可以,只能阻塞等待
加锁自动:DML语句会自动加排他锁手动:select * from t1 where id =1 for update;
种类
记录锁:只锁一条记录
间隙锁:会锁住一个区间
意向锁:加锁之前,先看一一下这张表有没有锁,快速判断,提交加锁效率
mvcc基于多版本的并发控制
当前读
本来根据默认的隔离级别,rr,一个事务中不可能读到别的事务提交的数据,但是,如果B事务把数据修改了,A事务在修改数据的时候,应该先读最新的数据,然后再修改,这才是合理的,如果根据rr隔离级别,是做不到的,所以有了mvcc的当前读,当事务中需要修改数据的时候,会获取该条记录的最新的记录,然后再去改数据;但是又不能完全解决问题,这个获取再修改是原子性的吗?和cas一样的道理
快照读
只读数据的时候,只会有快照读,不会触发当前读
高可用
主从复制
读写分离
sql优化
基础知识
数据类型
整数
tinyint(1字节)、samllint(2)、mediumint(3)、int(4)、bigint(8)
int无符号存储:2^32 -1有符号存储:-2^31 -(2^31 -1)
浮点
float(4字节)、double(8字节)、decimal
阿里规约:小数使用decimal,禁止使用float和double,f和d存在精度损失的问题,很可能在比较的时候,得不到准确的结果,如果存储范围超过decimal的范围,建议将数据拆成整数和小数部分,
字符
char(4字节)、varchar(变长,输入的长度+1字节)、text...
varchar(10)什么意思:5.x之后的版本代表,可以存储10个字符,utf-8的情况下,一个字符代表3个字节
时间
二进制等
redis
基本数据结构
string
应用场景
分布式锁
用redis实现分布式锁需要关注的点:1、获取锁和加锁的过程放在try/catch的外面,防止获取锁失败,但是执行释放锁的操作;2、设置超时时间,防止redis宕机,没有释放锁,导致其他线程永远获取不到锁;3、每个线程设置一个专属的value,在释放锁的时候,需要验证是不是当前线程该释放的锁,防止其他线程释放自己的锁;4、释放锁如果想要设置成原子的,则需要执行lua脚本;
缓存热点数据
缓存穿透
恶意查询,redis中没有,就去查mysql,mysql没有就返回null,如果存在大量的这样的查询,会给mysql造成压力
mysql中也没有的话,就返回null,同时在redis中存null,并设置超时时间
缓存击穿
缓存到期,这时候恰好有大量的查询,导致大量的查询打到mysql上
解决方案:将过期时间设置成晚上更新,或者不设置过期时间
缓存雪崩
实现方式:sds
自定义数据结构:包括len、free、buf好处:1、快速获取长度o(1)2、避免缓冲区溢出,增加长度时,会判断缓冲区buf长度是不是够用,不够用的话会申请空间3、空间预分配,<1M,增加相同的长度;>1M,增加1M
list
发布订阅
set
抽奖:SADD key {userId},SPOP/SRANDMEMBER key [count](从集合中随机挑选几个元素)
点赞👍:SADD like::{articleId} {userId} # 点赞SREM like::{articleId} {userId} # 取消赞SISMEMBER like::{articleId} {userId} # 检查用户是否点过赞SMEMBERS like::{articleId} # 获取所有点赞用户列表SCARD like::{articleId} # 获取点赞用户数
实现方式:无序的string集合
Zset
排行榜
Hash
表信息
bitmap
setbit 2021_02_21_log 201 1setbit 2021_02_21_log 202 1setbit 2021_02_22_log 2 1setbit 2021_02_22_log 201 1代表在2021_02_01 这天,201号童鞋签到了,202号同学也签到了
统计一天当中签到的数量:bitcount
统计三天内签到的同学,将三天的log做&运算然后调用bitpos就可以这个返回三天签到的同学
统计一位同学一年中签到的次数呢
签到
持久化
rdb
开辟一个子线程,根据持久化策略(比如一分钟内5个key值发生变化)就开始做持久化,这种情况下,就可能会造成数据丢失
数据的完整性要求不高数据量较大
aof
操作指令追加
数据量较小完整性要求较高
kafka
为什么要用kafka
为什么要用消息队列
解耦冗余/可恢复扩展灵活/峰值处理,双十一消峰处理顺序性
kfka比其他消息队列的优势
号称大数据杀手锏,很多大公司都在用吞吐量大,单机写入TPS约在百万条/秒而且有很好的后台管理页面scale语言,java风格,源码可读性较好
消息丢了怎么办
高性能和高吞吐量如何做的
写数据:内存写+磁盘顺序写(随机写,性能差)https://www.cnblogs.com/gxyandwmm/p/11432598.html
读数据:零拷贝(省去了os缓存到kafka进程的缓存 + kafka进程到socket的缓存),仅仅是os cache到socket发送一个描述符,os cache直接发送到请求的网关
kafka消费过程,跟zookeeper什么关系
使用场景:比如对同一个车源号多次修改,能够保证存储到同一个分区,统一分区的消息是绝对有序的,那消费也是有序的
es
mybatis
xml文件和mapper中方法的关联:通过namespace和id两维坐标定位的;为什么呢?
原因是,在初始化时,mybatis会将所有的sql语句放到一个容器当中,容器是一个map的数据结构,key=namespace+id,value=sql语句对象
mapper是个接口,代码中我们并没有实现类,实例化出来的呢?
动态代理+
mybatis核心流程
初始化:读取配置文件和注解中的信息,创建配置对象,包括数据库连接信息,所有的sql对象,填充到java内存封装请求:
MappedStatement:String NameSpace;String id;String sql;String ResultType;
0 条评论
回复 删除
下一页