• ASM及javassist字节码增强技术
    • MySQL GTID主从同步(见笔记)
    • volatile与MESI的关系
    • PG幻读问题
    • epoll
    • 深入理解socket
    • Redis大key及热key问题
    • Redis缓存击穿/雪崩
    • Redis分布式锁
    • 基因法与索引法分库分表
    • MySQL数据页清理
    • Linux连接上限
    • kafka多线程消费
    • http缓存机制
    • 脑裂问题与惊群,主从切换数据丢失
    • TCP中断如何处理
    • 分布式事务
    • 监控理论(见夜莺监控)
    • luence倒排索引原理
    • sychronized实现原理
    • Kafka幂等和事务原理
    • ES深度分页
    • volatile与MESI没有必然联系,MESI是volatile语义的一部分,可见性还是由MESI实现的,volatile只是告知CPU请立刻更新到缓存中(lock指令强制刷新缓存,由于重排序通常发生在store buffer,所以也实现了禁止重排序功能。因为store buffer会导致部分变量不会直接更新到缓存,而CPU后续的变量可能会直接先更新缓存导致的,x86没有无效队列),https://blog.csdn.net/foxException/article/details/119774421,store buffer用于存储修改的数据,invalid queue用于存储失效通知,待CPU处理。volatile的语义的作用是可见性和禁止重排序。其中可见性是因为CPU的MESI引入了store buffer产生的,禁止重排序也是,volatile的本质作用就是立刻写入缓存中
    • PG没有当前读,所以MVCC足够解决幻读,在不可重复读级别,并发的排它锁会导致其中一个事务失效;可重复读和串行化级别下,并发写其中一个事务会被终止
    • 跟IO多路复用有关,调用select的时候会将所有管理的socket传到内核检查socket状态,如果没有事件则会阻塞等到有一个socket有数据来唤醒,epoll在内核中维护红黑树socket,有数据时加入到就绪队列并唤醒epoll,响应epoll wait,将fd拷贝到用户态,删除就绪队列的fd,ET和LT的区别在于,LT会重新添加会就绪队列关于select/epoll的原理就跟笔记一样。poll与epoll需要先提到IO多路复用,相对于传统IO的一个处理线程处理一个socket,多路复用可以由一个线程处理多个socket,而处理的方式就是select
    • socket在linux抽象为文件,所有网络读写就是对文件的读写,所以也有对应的socket缓冲区。socket是操作系统对网络协议的抽象,把网络协议的处理封装起来,网络数据会缓存在socket缓冲中,对应用程序提供socket接口,程序就能够通过操作socket接口来操作网络数据
    • MySQL没有清理过程,只有手动触发通过alter或optimize table重建表文件,MySQL不会自动收缩表
    • Http缓存:1. 判断强缓存Cache-Control或者Expired是否存在,如果存在且没有过期;则直接使用浏览器缓存;2. 如果不存在强缓存或强缓存过期,则会检查协商缓存Etag和Last-Modified是否存在,如果存在则请求服务器带上相应的头;3. 由服务器决策返回304则可以继续使用缓存,否则需要过去最新的资源并返回200
    • Linux最大连接数:服务器的最大端口数为65535,但不代表只能有65535个连接,每个连接由5元组组成,元组完全相同才算同一个连接。TCP在accept创建的socket的源ip和源port都是相同的,而且一个socket只能绑定一个源端口。但会被单个进程可打开文件数限制,当然该限制没有规定最大值
    • Kafka客户端默认只支持1个Consumer1个线程处理,如果需要多线程,则是由一个consumer负责获取获取消息,然后再分发给线程池处理
    • 惊群:大量阻塞的线程在请求到达时被同时唤醒,但只有一个真正地工作,其他又重新阻塞,Nginx, epoll, zookeeper
    • 脑裂:Redis脑裂主要出现在哨兵(集群也可能),通过配置最少从服务器数量和从库响应主库最长等待ack时间解决,否则拒绝写入;MySQL脑裂GTID主主模式最少服务器数保证;Redis主从切换造成数据丢失与脑裂过程是一致的,其原因在于主服务器变为从的时候会清空本身所有数据,MySQL主从切换可以通过半同步复制实现。脑裂通常是因为集群因为网络原因主节点被认为宕机而发生主从切换,但实际上主服务器还在工作,造成脑裂;特别地,Redis在主从切换时旧的主服务器需要清空原有数据并全量同步新的主服务器
    • Redis大key问题:https://www.modb.pro/db/103715 ,单线程查询性能下降,会造成数据倾斜,删除时消耗的资源也比较大。避免写入大key(单string类型拆分成多个,其他类型控制在5000个以内),删除的时候使用lazy-free(逻辑删除,真正删除由后台线程处理)拆分或使用本地缓存;(考虑使用scan或unlink删除大key,scan获取多个元素再进行删除,而且scan会返回游标;unlink会使用异步线程处理删除任务,被动方式是内存淘汰使用lazyfree)热key问题:https://blog.csdn.net/xushiyu1996818/article/details/121326089,同样造成数据倾斜问题,使用客户端或代理层收集数据,也可以定时执行hotkeys命令。使用二级缓存减少走到Redis的访问量,对热key使用多副本,分散访问压力(例如生成随机数与key名称拼接从而实现随机访问)
    • 缓存雪崩:https://blog.csdn.net/a745233700/article/details/88088669,Redis宕机或大量缓存同时过期,事前保证过期均匀,事中互斥锁(分布式锁),事后尽快恢复缓存;缓存击穿:热点key失效,使用互斥锁;缓存穿透:查询不存在的数据,使用布隆过滤器
    • 分布式锁实现方式:https://zhuanlan.zhihu.com/p/42056183,1. 不同机器可以获得锁;2. 锁可以重入;3. 获得锁有超时;4. 持有锁需要有效时间保证不会造成死锁。数据库使用分布式锁简单,不需要引入别的中间件,单点故障需要自己考虑;但性能瓶颈在数据库上,不适合高并发场景,而且宕机后的死锁不好处理(定时扫描的话原有任务可能还在执行);zookeeper不需要担心死锁,但性能也没有太好,不会出现单点故障;使用Redis效率比较高,但是setnx会可能造成死锁,一般使用set ex px nx原子操作,但还有两个问题:线程还没执行完就到期了、线程释放时可能已经到期其他线程在持有锁导致把别的锁误删,对于第一个问题Redission使用watch dog每隔一段时间检查,如果快过期则增加过期时间,第二个问题设置一个标识号如果删除时与设置的不同则不执行删除;如果单点问题,则需要使用RedLock来在集群中使用分布式锁 | | 原理 | 优点 | 缺点 | | —- | —- | —- | —- | | 数据库 | 通过for update对资源进行加锁,长期阻塞通过字段保证锁持有有效时间 | 简单 | 性能较差,并且有数据库开销,存在单点问题 | | Redis |
      1. set ex px nx命令添加锁和超时时间
      1. 解锁是使用lua删除对应的key
      | 性能高 | https://www.cnblogs.com/wangyingshuo/p/14510524.html
      Redis锁改进的方式 | | RedLock | image.png
      半数以上节点 | 解决多机Redis主从切换的锁失效问题 | | | Redission | 只要线程一加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了「锁过期释放,业务没执行完」问题 | 解决锁释放了,业务没处理完的问题 | | | Zookeeper | 利用临时节点与 watch 机制。每个锁占用一个普通节点 /lock,当需要获取锁时在 /lock 目录下创建一个临时节点,创建成功则表示获取锁成功,失败则 watch/lock 节点,有删除操作后再去争锁。临时节点好处在于当进程挂掉后能自动上锁的节点自动删除即取消锁。 | | 可能发生羊群效应 |

    • 分库分表的方式有范围法和hash法,其中如果某个字段希望跟hash主键分到一个库就需要使用基因法,基因法是后N位(2^N个库),主键也是生成64-N与N位组合成一个主键,但再多一个字段就无法使用,需要倒排索引法(扩容?)

    • 分布式事务:https://xiaomi-info.github.io/2020/01/02/distributed-transaction/,XA依赖数据库的XA接口两阶段提交;TCC则是在业务层面处理回滚逻辑
    • luence倒排索引:https://blog.csdn.net/qq_31960623/article/details/118860928
    • sychronized原理,https://www.cnblogs.com/hongdada/p/14087177.html,底层是操作系统的互斥量Mutex,加锁是通过锁对象的monitor,每个monitor对象都有锁池EntryList和等待池waitset,sychronized会对同步代码块加上monitorenter和monitorexit指令;可重入性:每个锁关联一个线程对象和计数器,每次重入计数器加1,,每次退出同步代码,计数器减一,当为0时代表释放该锁
    • ES深度分页:https://developer.51cto.com/article/684507.htmlhttps://juejin.cn/post/7010660177791680520,两种方法scroll和search after,scroll本质上都要经过query阶段,但翻页时不需要重新聚合,只需要根据需要的id数去fetch,因为是预先聚合所以不是实时的; search after不是预先聚合每次根据上次最后一个value去各个分区取size个。ES查询原理,ES分页的问题,解决方法