编程
Redis LFU内存淘汰策略细究
Redis 的 LFU(Least Frequently Used,最不频繁使用)淘汰策略,是在 LRU 基础上做的“升级版”近似算法。它复用了对象头上同一个 24 位的 lru 字段,通过巧妙的编码和对数计数,用极小的内存代价,实现了对访问频率的近似跟踪。 下面从存储结构、计数器增减、淘汰决策到参数配置,逐一细究。 1. 24 位字段的位划分 每个 Redis 对象都有一个 lru 属性(24 位),在 LFU 模式下,它不再存放秒级时间戳,而是被拆成两段: 高 16 位:最后衰减时间(Last Decay Time,单位:分钟) 低 8 位:对数访问计数器(Logarithmic Counter,范围 0–255) 高 16 位:存储的是 (server.unixtime / 60) & 0xFFFF,即当前分钟时间戳的低 16 位。最大表示约 45 天,足够覆盖淘汰场景,即使回绕,只要间隔不超过 45 天就可以正确计算差值。 低 8 位:是一个 0–255 的频率计数器,但它不是访问次数的直接累加,而是经过对数平滑处理的“近似频率”。 当键被访问时,Redis 会调用 updateLFU(),先根据已流逝的时间衰减计数器,再概率性地递增计数器,最后把新的分钟时间戳和计数器重新编码写回 lru。 2. 计数器递增:对数增长 为了让 8 位计数器(0–255)既能表示低频也能区分高频,同时不让热门键快速打满,Redis 采用概率递增。 递增公式(源码级): double p = 1.0 / ((counter - LFU_INIT_VAL) * server.lfu_log_factor + 1); if ((random() & 0xFFFF) < p * 0xFFFF) counter++; LFU_INIT_VAL 默认为 5,新键的计数器初始值就是 5。 lfu_log_factor 是可配置的对数因子,默认 10。 随着 counter 增大,p 会越来越小,递增越来越难。 举例(factor = 10 时,典型访问次数与计数器值): ...
软考系统架构师 学习
本笔记基于考纲核心知识点整理,配合代码示例和记忆口诀,适合冲刺复习。 一、法律法规与标准化 1.1 著作权 类别 内容 不受保护 政府公文、法律条例、时事新闻 受保护 演讲稿、编写的图书、软件代码 归属时间 软件开发完成之日起自动产生 保护期限 50年(署名权、修改权、完整权永久保护) 著作权归属规则: 谁开发归谁 员工利用公司资源开发 → 归公司 职务作品无合同 → 归企业法人 改编作品 → 著作权归改编人 ⚠️ 处理过程(算法逻辑)不属于软件著作权保护对象,只保护代码表达形式。 受时间限制的权利(50年): 发表权、发行权、展览权、复制权 永久保护的权利: 署名权、修改权、保护作品完整权 1.2 其他知识产权 商标权:注册完成后才享有;保护对象为软件注册商标 专利权:专利注册完成后才享有 二、软件工程 2.1 软件开发模型对比 模型 适用场景 核心特征 瀑布模型 需求明确固定 阶段严格顺序,不可逆 增量模型 需求部分明确,需快速交付核心 分批次交付模块 原型模型 需求模糊,用户难以描述 先做原型再开发目标软件 螺旋模型 大型复杂高风险项目 每轮增加风险评估环节 喷泉模型 面向对象开发 无严格阶段划分,阶段可交叉迭代 V模型 可靠性要求高 开发与测试一一对应 W模型 质量要求高 开发与测试同步进行 瀑布模型阶段: 需求分析 → 系统设计 → 详细设计 → 编码 → 测试 → 维护 (每个阶段完成后才进入下一阶段) 螺旋模型四象限: ① 制定计划 ② 风险分析 ③ 实施工程 ④ 客户评估 2.2 敏捷开发方法对比 方法 核心理念 关键特征 XP(极限编程) 把传统开发做到极致精简 结对编程、测试先行、持续集成 SCRUM 短周期冲刺 三会议(站会/计划/回顾),需求按商业价值排序 水晶开发 以人为本 最轻量灵活,重团队协作,文档少 FDD 特性驱动 五步:建模→功能清单→规划→设计→实现 ASD 适应性开发 猜测→协作→复盘,三个非线性阶段 DSDM 动态系统开发 八条原则,聚焦业务价值按时交付 开放源码 全球协作 高并行排障,代码公开 SCRUM 三大会议: 每日站会、迭代计划会、复盘回顾会 ...
ElasticSearch 学习
1. 基础篇 1.1 起源:Lucene Lucene:Apache 开源的 Java 全文搜索引擎类库。 优势:易扩展、高性能(纯 Java,可嵌入)。 缺点:使用复杂,需处理索引创建、查询解析等底层细节,无分布式支持。 Elasticsearch 基于 Lucene 构建,提供分布式、易用的 RESTful API。 1.2 技术栈(ELK) Elasticsearch:存储、搜索和分析引擎。 Logstash:服务器端数据处理管道,采集、转换数据后发送至 ES。 Kibana:可视化平台,制作图表、仪表板,管理 ES。 Beats:轻量型数据采集器,发送到 Logstash 或 ES。 1.3 使用 Docker 安装 Elasticsearch(单节点): docker run -d --name es \ -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \ -e "discovery.type=single-node" \ -v es-data:/usr/share/elasticsearch/data \ -v es-plugins:/usr/share/elasticsearch/plugins \ --privileged \ --network testNet \ -p 9200:9200 -p 9300:9300 \ elasticsearch:7.12.1 9200:HTTP API 端口 9300:内部节点通信端口 discovery.type=single-node:单节点模式(测试用) Kibana: docker run -d --name kibana \ -e ELASTICSEARCH_HOSTS=http://es:9200 \ --network=testNet \ -p 5601:5601 \ kibana:7.12.1 1.4 倒排索引(Inverted Index) 正向索引:文档 ID → 文档内容。适合根据 ID 精确查找,但做模糊搜索需遍历所有文档,效率低。 倒排索引: 文档(Document):ES 中存储的一条 JSON 数据。 词条(Term):文档经过分词后的最小单元。 结构:词条 → 文档 ID 列表(及位置、频率等)。 优点:快速定位包含某个词条的所有文档,实现高效全文搜索。 1.5 分词器(Analyzer) 将文本拆分为词条(term)的组件,由三部分组成: ...
AWS 学习
面向系统架构师认证,结合 Java 后端视角整理。核心思路:每个服务解决什么痛点、何时选它、和类似服务怎么区分。 一、存储 Storage 1.1 三种存储类型对比 类型 代表服务 访问单元 典型场景 块存储 EBS, EC2 Instance Store 数据块(Block) 数据库、OS 磁盘 文件存储 EFS, FSx 文件/目录树 多实例共享、NFS/SMB挂载 对象存储 S3 对象(Object + Key) 静态资源、备份、数据湖 块存储 → 像本地硬盘,OS看到的是裸设备,自己格式化挂载 文件存储 → 像 NAS,多台机器可以同时 mount 同一个目录 对象存储 → 像 HTTP PUT/GET 的 Key-Value,无目录概念,靠前缀模拟 1.2 Amazon S3 核心功能速查: 功能 说明 常见考点 Versioning 同一 Key 保留多个历史版本 开启后才能用 CRR / MFA Delete CRR(跨区域复制) 异步复制到另一 Region 灾备 DR、降低延迟 Transfer Acceleration 通过 CloudFront 边缘节点加速上传 上传到遥远 Region 时使用 Lifecycle Policy 对象按年龄自动迁移存储类 节省成本核心手段 S3 File Gateway 本地 SMB/NFS 映射到 S3 混合云文件迁移 Intelligent-Tiering 自动在 Standard ↔ IA 间切换 访问模式不可预测时使用 S3 存储类选择决策树: ...
Spring Cloud 学习
1. 服务拆分与远程调用 1.1 为什么要拆分服务? 单体应用随业务增长面临:部署慢、扩展性差、技术栈固化等问题。微服务将其拆分为独立部署、独立扩缩容的小服务,每个服务只负责一个业务域。 拆分原则: 单一职责:每个服务只做一件事 高内聚低耦合:服务内部紧密,服务之间松散 数据独立:每个服务拥有独立数据库 1.2 用户登录流程(微服务视角) Client → Gateway(鉴权) → 业务微服务A → 微服务B(OpenFeign) ↓ Nacos(服务发现) 1.3 RestTemplate — 微服务间原始调用 RestTemplate 是 Spring 提供的 HTTP 客户端,可用于微服务间调用,但代码繁琐、不支持负载均衡,是 OpenFeign 出现前的过渡方案。 // 注册为 Bean,并开启负载均衡 @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } // 调用方式(服务名替代 IP:Port) String url = "http://user-service/api/users/" + userId; User user = restTemplate.getForObject(url, User.class); ⚠️ RestTemplate 已逐渐被 OpenFeign 取代,生产中优先选择 OpenFeign。 2. 服务治理 — Nacos 注册中心 2.1 解决的问题 微服务实例 IP / 端口动态变化,调用方无法硬编码地址。注册中心提供: ...
SSM框架 学习
一、Spring IoC 容器 1.1 容器体系结构 BeanFactory(顶层接口) └── ApplicationContext(常用接口,扩展了BF) ├── ClassPathXmlApplicationContext(XML配置) ├── FileSystemXmlApplicationContext(文件路径XML) └── AnnotationConfigApplicationContext(注解配置) BeanFactory vs ApplicationContext 核心区别: 特性 BeanFactory ApplicationContext Bean 初始化时机 懒加载(第一次 getBean 时) 饿加载(容器启动时) 功能 基础 IoC IoC + 事件发布 + 国际化 + AOP等 使用场景 资源极度受限的嵌入式 99% 的业务场景 ApplicationContext 为什么没有 close()? ApplicationContext 接口本身不定义 close(),是为了保持接口的通用性(不是所有容器都能/需要被关闭,如 Web 容器)。但其实现类 AbstractApplicationContext 实现了 Closeable,可以强转后调用,或用 ConfigurableApplicationContext 接口接收。 1.2 延迟加载(Lazy Loading) // 注解方式:@Lazy 让 Bean 在第一次被使用时才初始化 @Bean @Lazy public HeavyService heavyService() { return new HeavyService(); } // XML方式: // <bean id="heavyService" class="..." lazy-init="true"/> 适用场景:初始化代价高、启动时不一定用到的 Bean(如某些连接池、第三方SDK客户端)。 ...
MyBatis-Plus 学习
1. 简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 核心特点: 无侵入:引入 MP 不会对现有 MyBatis 工程产生影响,犹如丝般顺滑。 损耗小:启动即会自动注入基本 CRUD,性能基本无损耗。 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅通过少量配置即可实现单表大部分 CRUD 操作。 支持 Lambda 形式调用:通过 Lambda 表达式,安全高效的编写查询条件,防止字段名误写。 内置代码生成器:通过少量配置即可生成 Mapper、Service、Controller 等代码。 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置后即可使用。 官网:https://baomidou.com/ 2. 基本用法 2.1 引入依赖 在 Maven 项目 pom.xml 中添加: <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> <!-- 请按最新版本 --> </dependency> 如果是传统 Spring 项目,可引入 mybatis-plus 核心依赖并自行配置。通常 Spring Boot 项目直接使用 starter。 2.2 定义实体类 @Data public class User { private Long id; private String name; private Integer age; private String email; } 2.3 编写 Mapper 接口 继承 BaseMapper<T> 即可获得 CRUD 能力: ...