Memcached 和 Redis 内存管理 Memcached 和 Redis 内存管理传统的 C 语言的 malloc/free 函数是最常用的分配和释放内存的方法,但是这种方法存在着很大的缺陷 不匹配的malloc和free容易造成内存泄露 频繁调用会造成大量内存碎片无法回收重新利用,降低内存利用率 作为系统调用,其系统开销远远大于一般函数调用 MemcachedMemcached默认使用Slab Allocation机制 2024-09-20 #Redis
Redis 能存多少个 Key 数据结构Redis 的键值对存在哪里? 哈希表 dictEntry 存储的是实际键值对,定义如下 12345678910typedef struct dictEntry { void *key; union { void *val; uint64_t u64; int64_t s64; double d; 2024-09-07 #Redis
MyBatis 缓存设计思想 缓存本质其实就是一个 Map,MyBatis 的缓存最基本的实现是 PerpetualCache,内部使用了 HashMap 来保存数据 缓存一般还有额外的功能比如淘汰策略,最大时长等,如何扩展这些功能? 扩展类的功能有 2 种,继承和组合,但是 MyBatis 提供了很多功能并且有的是动态组合的,比如容量上限 512,淘汰策略 LRU… 如果是集成的话,那要把所有排列组合都实现一遍,会导致类爆炸 2024-08-30 #MyBatis
MyBatis 日志设计思想 整体架构用了门面模式,对外暴露 SqlSession 接口 日志模块,采用了适配器模式 如果需要接入多个第三方 SDK 来满足自己的业务需求,但是 SDK 的接口定义与你的业务不兼容,又不能修改第三方 SDK 的代码,可以用适配器设计模式解决 MyBatis 定义了自己 Log 接口,为大部分主流日志框架都实现了 Adapter 适配器 1234567891011121314151617pu 2024-08-23 #MyBatis
ThreadPoolExecutor ThreadPoolExecutor线程池对象,如果里面添加了任务,如果不手动调用 shutdown 方法,那么这个对象永远不会被 GC 首先看一下 ThreadPoolExecutor 的源码结构 ThreadPoolExecutor 里面有一个内部类 Worker 这个内部类实现了 Runnable 接口 这个 Worker 类里有一个 runWorker 方法,是保证线程不断运行的原理 12 2024-08-20 #源码
一致性哈希 一致性哈希问题是为了解决请求负载均衡的 负载均衡算法在多节点分布式系统中,如何有效分配客户端请求以实现负载均衡 轮询算法 加权轮询算法 哈希算法 上面两中对于数据分片就不适用了,比如缓存的 key 分布在不同的节点上,通过哈希函数和取模运算可以将请求映射到特定节点 一致性哈希 一致性哈希算法普通哈希算法存在问题,当节点数增加的时候,需要重新计算映射关系,也要迁移数据 比如一开始有 2024-08-16 #分布式
CountDownLatch CountDownLatch 类存在一个内部类 Sync 继承自 AbstractQueueSynchronizer 所以 CountDownLatch 也是基于 AQS 实现的,其中 state 表示前面有几个线程需要等待 核心函数内部类结构类中只有一个成员变量 Sync 这个类继承了 AbstractQueueSynchronizer 1234public class CountDownLa 2024-08-10 #JUC
Redisson 延迟队列 Redisson 延迟队列底层实现底层用 3 个队列实现 消息延迟队列,Zset 类型,按照过期时间顺序存放消息列表 消息顺序队列,List 类型,按照添加顺序存放消息列表 消息目标队列,List 类型,存放到期的消息,供消费者获取 消息来的时候先插入【消息延迟队列】和【消息顺序队列】 最后消费者在【消息目标队列】进行消费的,消费者只需要阻塞等待【消息目标队列】即可 消息移动在初始化延迟队列的 2024-07-30 #Redis
配置中心的长轮询 配置中心的长轮询配置中心是为了解决传统静态配置修改重启应用的问题,Nacos 和 Apollo 都是通过长轮询来实现动态推送的,而不是长连接 推拉模式数据交互有两种模式:【推模式 push】和【拉模式 pull】 推模式是客户端和服务器建立好长链接,服务器的数据推送到客户端 优点,及时,一旦有数据变更,客户端立马能感知到 缺点,不知道客户端消费能力,可能导致数据堆积 拉模式是客户端主动向服务 2024-07-23 #配置中心
MyBatis-step02 这是一个流程, 通过 SqlSessionFactory 开启一个 SqlSession SqlSession 里有成员变量 MapperRegistry MapperRegistry 里面通过包路径扫描,得到了一个 map 这个 map 封装了接口,跟它的代理类工厂 可以通过 get 的方式获得代理类工厂,用工厂的静态方法 new 出来一个代理对象 使用工厂模式可以屏蔽创建细节,延迟创建过 2024-07-22 #MyBatis