分库我们是不做的, 因为我们用的是OceanBase, 他是一个原生的分布式数据库, 所以牵扯到分库的时候都是业务上存在拆分情况, 我们才进行分库操作.分区是按照业务主键分的. 这样就能分表是将一个大表按照业务拆分成一个主表, 若干个小表, 加快了查询速度.
mysql执行每个sql语句都需要经过分层处理后才能交给数据引擎处理. 连接层:管理链接和权限校验,例如JDBC分析器:词法分析和语法分析.优化器: 执行计划生成和索引选择执行器:操作引擎,返回结果.存储引擎:存储数据, 提供读写接口. 更新语句与查询语句还有些不同, 更新语句涉及到两个log, binLog和redoLog, 因为现在谈论的都是Innodb, Innodb支持事务是通过在写入binLog之前, 先写入到redoLog中. 然后写入到到binLog中, 最后写入ChangeBuffer, 最终会在changeBuffer中合并为顺序写入磁盘的操作.
redoLog和binLog 两者一起保证了Innodb对事务的支持. 通过的是两阶段提交机制, 先写入变更内容到redoLog, redoLog是四个循环文件, 被数据库执行后会被擦除, 而binLog则是MySQL的变更内容记录文件.
通过binLog同步, binLog同步有三种方案,
row
statement
mix
一般推荐使用mix, 如果需要主从同步, 则推荐在RC级别下必须使用statement或者mix, RR级别可以使用statement.
使用数据库中间件
所有的读写都走数据库中间件,通常情况下,写请求路由到主库,读请求路由到从库
记录所有路由到写库的key,在主从同步时间窗口内(假设是500ms),如果有读请求访问中间件,此时有可能从库还是旧数据,就把这个key上的读请求路由到主库
在主从同步时间过完后,对应key的读请求继续路由到从库
常用的数据库中间件:canal、otter等
优点:保证数据绝对一致
缺点:实现成本较高
缓存记录写key法
如果key要发生写操作,记录在cache里,并根据经验设置的cache超时时间,例如500ms, 然后修改主数据库
读
先到缓存里查看,对应key有没有相关数据
有相关数据,说明缓存命中,这个key刚发生过写操作,此时需要将请求路由到主库读最新的数据
如果缓存没有命中,说明这个key上近期没有发生过写操作,此时将请求路由到从库,继续读写分离
优点: 相对数据库中间件,实现成本较低
缺点: 为了保证“一致性”,引入了一个cache组件,并且读写数据库时都多了缓存操作
简单,不写了, 主要就是每级缓存干了什么, 怎么从一级演变到三级的, 解决了什么问题.
简单,不写了, 提一下@Conditional注解 和spring.factories文件.
IO密集型配置线程数经验值是:2N,其中N代表CPU核数。
CPU密集型配置线程数经验值是:N + 1,其中N代表CPU核数。
通过redis提供的setnx指令, 超时问题是通过引入Redisson框架中的看门狗机制来解决的. 这个框架底层是lua脚本保证发送命令的setnx和expire的原子性, 然后定期给还在使用的分布式锁增加过期时间.
这个就是讲一下扩容数组和双向链表的区别, 一般推荐使用ArrayList.
按照1.8之前的Segement说下, 1.8之后的锁红黑树的根节点和链表的头节点.
这个当时太紧张了, 没答出来满意的答案, 只说了用栈或者递归.如果要求O(1)空间的话, 直接逆序,然后输出,然后再逆序回去. 就是O(1).
主要就是公钥和私钥加解密, 然后需要一个可信机构颁发证书,
主要是五个方面,
rocketMQ底层是基于文件系统的, 这基本是读写最快的方案,
rocketMQ 基于文件系统实现了读写分离, 生产者写入的文件是commit Log, 这个文件是按照 topic划分, 没个新消息都是顺序写入的, 顺序写入的效率比随机写入高几百倍. 然后读文件是采用的comsuer Queue, 这个queue的每个元素都只存储了message的地址和大小, 消费者需要根据地址去commitLog里查询信息. 直接使用地址读取 效率也很高.
rocketMQ 底层采用了Netty作为 网络框架, Netty底层使用了NIO, 也就是 IO多路复用, 非常见的BIO , 这也是效率高的原因之一
RocketMQ 底层采用了MMap, 零拷贝技术, 原来一个java系统需要四次拷贝
操作系统读取文件到系统内存
系统内存拷贝到应用系统内存
应用系统拷贝到Socket缓存中
Socket缓存拷贝到网卡内存种
使用Mmap的话, 就会直接从系统内存到网卡内存, 省去了应用和Socket缓存得拷贝, 效率提升了.
此外, 源码中使用了较多得 多线程编程, 因为MQ是IO频繁应用, 使用多线程可以有效增加CPU的吞吐量.
Elasticsearch写入数据流程
客户端随机选一个节点发送请求,被选择的节点为协调节点(coordinating node)协调节点计算并转发到真正的处理节点(主分片在的节点), 处理节点写入请求, 并同步给分片节点, 协调节点收到所有分片节点的相应信息,后, 返回结果.
Elasticsearch读取数据流程
客户端随机选一个节点发送请求,被选择的节点为协调节点(coordinating node)协调节点查询集群状态信息并使用round-robin随机轮询算法计算出去此次请求的节点(主分片节点和副本节点随机分配),最后处理后的信息原路返回.
Elasticsearch检索数据流程
客户端发送请求到一个协调节点, 协调节点将搜索请求转发到所有的shard对应的primary shard或replica shard也可以每个shard将自己的搜索结果(其实就是一些doc id),返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果接着由协调节点,根据doc id去各个节点上拉取实际的document数据,最终返回给客户端