编程Cookbook

编程Cookbook

🎉 欢迎您来到 编程Cookbook,关注微信公众号 「编程Cookbook」 ,获取第一手资料。 🔭 编程Cookbook,我们的初衷和这个名字一样,像制定传统食谱一样,打造“编程食谱”。🌱 这里专注于分享编程知识,包括但不限于编程语言知识,数据库,中间件等后端/服务端知识,如果你是初学者,或者正在准备面试,那么恭喜你,来对了!
MySQL数据库——事务介绍
MySQL

MySQL数据库——事务介绍

大家好,这里是编程Cookbook。本文详细介绍MYSQL的事务,包括ACID、隔离级别、以及如何解决并发带来的问题。 MySQL事务是对数据库操作的一组处理逻辑单元,通常包括一系列的SQL语句,事务保证了这些语句要么全部成功执行,要么全部失败后回滚。 事务的特性:ACID MySQL中的事务管理机制符合ACID特性,确保数据的一致性、可靠性和完整性。分别是: 1. 原子性(Atomicity) 2. 一致性(Consistency) 3. 隔离性(Isolation) 4. 持久性(Durability) 1. 原子性(Atomicity) 定义: * 事务中的所有操作要么全部完成,要么全部不做,不能只执行部分操作。换句话说,事务是“原子”级的,事务的操作不可分割。 * 如果事务在执行过程中发生错误,所有已执行的操作都会回滚,数据会恢复到事务开始之前的状态。 实现原理: 原子性通过 undo log 来实现。事务执行过程中,如果发生错误或用户执行了回滚(
21 min read
MySQL数据库——索引介绍
MySQL

MySQL数据库——索引介绍

大家好,这里是编程Cookbook。本文详细介绍MySQL数据库中的索引,包括索引结构设计(B+树、哈希等)、用途(主键索引、唯一索引等)、聚集索引和非聚集索引,以及索引创建和使用的原则等。 按底层数据结构分类 MySQL 提供了四种主要的索引实现,每种索引类型有不同的应用场景和特点。以下是这四种索引类型: 索引类型 适用场景 支持的操作 优缺点 存储引擎支持 B+树 索引 常规查询(等值、范围、排序) 等值查询 (=)、范围查询 (>、<)、排序 (ORDER BY)、like、联合索引 优点:高效适配大多数查询操作 缺点:不适合哈希快速定位 InnoDB 和 MyISAM ,Memory(默认情况下是使用哈希索引) 哈希索引 等值查询 等值查询
20 min read
Redis数据库——Redis快的原因
Redis

Redis数据库——Redis快的原因

大家好,这里是编程Cookbook。本文详细介绍redis为什么这么快的原因,这里是本系列文章的总结篇(后面可能会补充一些内容,或者在原文上进行更新迭代),将从各方面出发解释为什么redis快,受欢迎的原因。 Redis 的高性能主要归功于其以下几个设计和实现特性: 内存 详细内容参考本系列文章中的内存部分: * 《Redis数据库——内存淘汰机制》 * 《Redis数据库——内存分配器》 * 《Redis数据库——内存预分配》 内存数据库 Redis 是一个 内存数据库,它将所有的数据存储在内存中,而不是磁盘上。内存访问速度远高于磁盘访问速度,这使得 Redis 在数据读写上非常快。 预分配内存 Redis 使用 内存池 来减少内存分配和回收的开销。内存池为 Redis 提供了高效的内存管理,避免了频繁的内存分配和回收操作,提高了性能。 数据结构 详细内容参考本系列文章中的数据结构部分: * 《Redis数据库——数据结构类型》 * 《Redis数据库——Hash(哈希)的扩容机制(rehash)》 * 《Red
5 min read
Redis数据库——单线程和并发请求
Redis

Redis数据库——单线程和并发请求

大家好,这里是编程Cookbook。本文详细介绍为什么Redis数据库使用单线程还这么快,以及如何处理并发请求。 Redis 是一个 单线程 的应用,这意味着 Redis 处理所有客户端请求的核心逻辑是在单个线程中完成的。尽管 Redis 使用单线程处理客户端的请求,但它的高性能并不受到影响,官方表明 redis 可以做到每秒近10w的并发。下面是对 Redis 单线程设计的详细介绍。 为什么 Redis 使用单线程? Redis 的单线程设计并不是一个随意的选择,而是基于以下几个关键因素: * CPU瓶颈不明显:在 Redis 中,瓶颈通常不是 CPU 的计算能力,而是 网络 I/O 和 内存访问。大多数操作都可以在内存中进行,且 Redis 的数据结构和操作都经过高度优化。 * 减少多线程开销:在多线程模型中,操作系统需要进行 线程切换 和 锁管理,
13 min read
Redis数据库——Cluster集群模式
Redis

Redis数据库——Cluster集群模式

大家好,这里是编程Cookbook。本文详细介绍Redis数据库的Cluster集群模式,包括工作原理,哈希槽,路由和配置原理等。 什么是 Redis Cluster 集群? Redis Cluster 在 3.0 版本中引入,是 Redis 的集群模式解决方案。提供了一种原生的分布式集群解决方案,用于解决 Redis 的水平扩展(sharding)问题【类似MySQL的分库分表】,自动将数据划分为多个分片(Shards),每个分片由一个主节点(Master)负责。每个主节点可以有多个从节点(Slave)用于数据冗余备份。 Redis Cluster 由多个节点组成,节点之间通过内部通信协议进行数据交换和协作。Redis Cluster 采用分布式哈希(hashing) 方式来管理数据,通过将数据分片并分配给不同的节点,确保 每个 Redis 节点只管理一部分数据。整个集群由多个 Redis
24 min read
Redis数据库——Sentinel哨兵机制
Redis

Redis数据库——Sentinel哨兵机制

大家好,这里是编程Cookbook。本文详细介绍Redis的Sentinel哨兵机制,包括其原理,哨兵选举,配置等内容。 Redis 哨兵机制(Redis Sentinel) 什么是 Redis 哨兵机制? Redis 哨兵(Sentinel)是 Redis 提供的高可用性解决方案,旨在确保 Redis 服务的高可用性和自动故障转移。它通过监控 Redis 主节点和从节点的运行状态,自动检测故障并实现故障转移,保证系统在出现故障时能够自动恢复,避免单点故障导致的服务中断。 Redis 哨兵机制由多个哨兵实例组成,这些实例彼此协作来监控 Redis 节点的状态。每个哨兵实例都可以独立工作,但它们之间会交换信息,以确保整个系统的一致性。其由下面的内容组成: * 哨兵节点:每个哨兵节点独立运行并执行监控、故障检测、故障转移等任务,并 不负责读写数据。Redis 哨兵需要至少 三个哨兵节点,并且最好是 奇数个哨兵节点来参与选举投票。 * 主节点:负责处理写请求的
11 min read
Redis数据库——主从复制
Redis

Redis数据库——主从复制

大家好,这里是编程Cookbook,关注公众号「编程Cookbook」,获取更多面试资料。本文详细介绍Redis的主从复制模式,包括作用,原因,工作原理,同步流程等。 主从复制 什么是 Redis 主从复制? Redis 主从复制是一种将主节点(master)上的数据同步到其他从节点(slave)Redis 实例的机制。数据复制是单向的,只能从主节点同步到从节点,或者层级复制。 * 主节点(Master):负责写操作。 * 从节点(Slave):负责读操作,复制主节点的数据。 * 默认配置:每台 Redis 服务器默认启动时都是主节点(Master),但是通过配置,可以将某些 Redis 服务器设置为从节点(Slave),从节点是通过配置来指定的,不是自动的。 * 树形结构:一个主节点可以有多个从节点,一个从节点只能有一个主节点。 节点数量: * 1个主节点,多个从节点 是标准的主从复制架构。
28 min read
Redis数据库——部署模式
Redis

Redis数据库——部署模式

大家好,这里是编程Cookbook。本文简要介绍Redis的部署模式,包括主从复制、哨兵机制、集群模式等。后面会详细介绍每一种部署模式,本文为各部署模式的简要介绍。 Redis 支持多种部署模式来提高性能、扩展性和高可用性。主要的部署模式包括: 单节点模式 * 适用于小型应用,只有一个 Redis 实例。虽然简单,但无法应对单点故障,也不能横向扩展。 * 适用场景:适用于小型应用或者开发/测试环境,但不可用于生产环境中需要高可用性和扩展性的系统。 主从复制模式 * 适用于 读多写少的场景。通过主从复制,主节点负责处理写操作和一部分读操作,从节点处理更多的读请求。 * 适合扩展系统的读取能力,但存在主节点故障时的单点风险。 * 适用场景:适用于读多写少的应用,通过从节点扩展读取能力,提高整体性能。 后续文章:《Redis数据库——主从复制》 Redis Sentinel(哨兵) * Redis Sentinel 是 Redis 的 高可用解决方案,它监控 Redis
4 min read
Redis数据库——持久化机制
Redis

Redis数据库——持久化机制

大家好,这里是编程Cookbook。本文详细介绍Redis的持久化机制,目标是将内存中的数据持久化到磁盘,以保证数据的可靠性和在重启后的恢复能力。 Redis 提供了三种持久化机制:RDB(Redis Database Snapshot) 、AOF(Append Only File)以及二者结合的混合持久化,以及一种混合模式(Hybrid Persistence)。这些机制的目标是将内存中的数据持久化到磁盘,以保证数据的可靠性和在重启后的恢复能力。 * RDB:在指定的时间间隔能对你的数据进行快照存储。 * AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。 * 混合持久化:在 Redis 4.0 引入,通过结合 RDB 和 AOF 的特性,既保留 RDB 的高效性,又降低 AOF 文件大小和启动时间。 Redis 默认的持久化机制取决于 Redis 的配置,但通常情况下,Redis 默认启用了
14 min read
Redis数据库——布隆过滤器(BloomFilter)
Redis

Redis数据库——布隆过滤器(BloomFilter)

大家好,这里是编程Cookbook。本文详细介绍Redis的布隆过滤器,解决缓存穿透的原理,及其改进的计数型布隆过滤器。 布隆过滤器概述 布隆过滤器(Bloom Filter)是一种概率型数据结构,用于检测某个元素是否在一个集合中。其特点是能告诉你某个元素“一定不存在 或者 可能存在”于某个集合中。布隆过滤器实际上是由一个很长的二进制向量和多个随机映射函数构成: 二进制向量:由0和1组成,初始状态为0。 * 0表示某元素一定不在集合中。 * 1表示该元素可能在集合中。 用途 布隆过滤器广泛应用于需要高效处理大规模数据的场景,尤其是减少磁盘I/O或网络请求的场合。例如: * 网页 URL 去重:通过布隆过滤器检查网址是否已存在,若已存在则不再读取。 * 垃圾邮件识别:通过发送方地址命中布隆过滤器的黑名单来过滤垃圾邮件。 * 黑名单:用于检测某个元素是否在黑名单中。 * 查询加速:尤其是基于键值对(KV)结构的数据查询。 * 集合元素重复判断:判断一个元素是否已经出现。 * Redis 缓存穿透问题:避免不必要的缓存查询。 原理
8 min read
Redis数据库——ZSet的底层实现(跳表)
Redis

Redis数据库——ZSet的底层实现(跳表)

大家好,这里是编程Cookbook。本文详细介绍ZSet数据类型中跳表的底层实现,包括基本特点和常用操作。 ZSet(有序集合) 概述 ZSet(Sorted Set,有序集合) 是 Redis 提供的一个非常强大的数据结构。它是一个 没有重复成员 且每个成员都关联着一个 分数(score) 的集合,Redis 会根据成员的分数对它们进行 自动排序。这个数据结构在许多需要有序数据的场景中非常有用,如排行榜、带有优先级的任务队列等。 ZSet 提供了非常高效的操作支持,如按排名查询、按分数查询、获取范围内的元素等,且在执行这些操作时有着较低的时间复杂度。 基本特点 * 成员唯一性:ZSet 中的每个元素都是唯一的(没有重复的成员)。 * 分数(score):每个成员都有一个与之关联的分数,分数通常是浮动的数值,用于排序。Redis 会根据分数值对成员进行升序排序。 * 有序性:ZSet 内部元素会根据分数(score)进行自动排序,成员可以通过分数排名进行快速查找。
10 min read
Redis数据库—— Hash(哈希)的扩容机制(rehash)
Redis

Redis数据库—— Hash(哈希)的扩容机制(rehash)

大家好,这里是编程Cookbook。详细介绍 Hash(哈希)的扩容机制( rehash )、源码、以及扩容和缩容过程。 Redis 的 Hash 类型是一个非常重要的数据结构,用于存储键值对的映射关系。它背后使用的是一种哈希表(hash table)结构,提供高效的 O(1) 时间复杂度进行插入、查找和删除操作。然而,当哈希表中的元素逐渐增多时,可能会触发哈希表的 扩容(rehash) 操作,以保证数据结构的高效性和性能。 Redis 字典(dict)结构 Redis 中的字典(dict)是一个使用哈希表实现的高效数据结构,它包含以下基本元素: * 键值对:每个元素是一个 key 和 value 的配对,Redis 通过哈希表将 key 映射到 value。
17 min read
Redis数据库——内存预分配
Redis

Redis数据库——内存预分配

大家好,这里是编程Cookbook。本文详细介绍Redis的内存预分配策略,在使用各数据结构类型时,内存是如何变化的,以及触发底层数据结构变化的条件。 Redis 的内存预分配策略是一种优化手段,用来 减少频繁的内存分配和释放操作对性能的影响。通过预先分配足够的内存,Redis 可以提高操作效率(在很多编程语言,如Go的切片,中都有实现),尤其是在高并发场景下。 什么是内存预分配? * 定义: Redis 在某些数据结构(如字符串、列表、哈希等)存储数据时,不是每次都按照精确的内存需求分配,而是会额外预留一部分内存空间。 * 目的: * 减少频繁的内存分配系统调用。 * 提高数据结构扩展时的性能。 * 降低内存碎片化的风险。 各数据结构的实现 Redis 的多个数据结构会使用内存预分配策略,包括: String(字符串) * 背景:Redis 的字符串类型基于 SDS 实现,支持动态扩容。 * 触发条件: * 当字符串长度超过当前分配的内存容量。 * 扩容策略:
9 min read
Redis数据库——内存分配器
Redis

Redis数据库——内存分配器

大家好,这里是编程Cookbook。本文详细介绍Redis数据库的内存分配器,这是redis为什么这么快的原因,以及其作为内存数据库的内存管理策略。 Redis 的内存分配器 Redis 的内存管理设计对性能和内存利用率有重要影响。其内存分配依赖底层的内存分配器和自身的一些优化机制。 内存分配器的作用 Redis 是一个基于内存的数据库,需要频繁地进行内存分配和释放操作。内存分配器的性能和设计直接影响 Redis 的整体性能。 * 内存分配器的主要职责: * 高效分配和释放内存。 * 尽量减少内存碎片。 * 提供线程安全的并发支持(多线程场景)。 Redis 支持的内存分配器 Redis 支持多种内存分配器,常见的有以下三种: 分配器 优点 缺点 使用场景 jemalloc 高性能、低碎片率、多线程支持【内存利用率高】 小对象(<4KB)分配速度略低于 tcmalloc Redis 默认,推荐使用 libc 简单易用,操作系统默认 性能和碎片控制较差 非高并发、低性能需求场景
9 min read
Redis数据库——8种内存淘汰机制
Redis

Redis数据库——8种内存淘汰机制

大家好,这里是编程Cookbook,关注公众号「编程Cookbook」,获取更多面试资料。本文详细介绍Redis的8种内存淘汰机制。 过期键删除策略 Redis 为管理内存,对设置了过期时间的键采用了以下三种删除策略: 1. 定时过期: * 描述:为每个设置了过期时间的键创建一个定时器,到达过期时间立即清除。 * 优点:对内存很友好,过期数据能及时清除。 * 缺点:需要消耗大量的 CPU 资源来处理定时器,影响缓存响应时间和吞吐量。 2. 惰性过期: * 描述:只有在访问某个键时才判断其是否过期,过期则清除。 * 优点:最大化节省 CPU 资源。 * 缺点:可能会有大量过期键未被访问而占用内存。 3. 定期删除: * 描述:每隔一定时间扫描 expires 字典中的部分键,清除过期键。 * 优点:折中策略,通过调整扫描时间间隔和
6 min read
Redis数据库——Redis雪崩、穿透、击穿
Redis

Redis数据库——Redis雪崩、穿透、击穿

大家好,这里是编程Cookbook。本文先简要介绍为什么需要使用Redis,以及过期键的删除策略,进而详细介绍Redis雪崩、穿透、击穿的发生场景和解决方案。 前情提要 为什么使用redis? 1. 提高性能:缓存査询速度比数据库查询速度快(内存Vs硬盘); 2. 提高井发能力:缓存分担了部分请求,支持更高的并发。 Redis 的过期键删除策略 Redis 为管理内存,对设置了过期时间的键采用了以下三种删除策略: 1. 定时过期: * 描述:为每个设置了过期时间的键创建一个定时器,到达过期时间立即清除。 * 优点:对内存很友好,过期数据能及时清除。 * 缺点:需要消耗大量的 CPU 资源来处理定时器,影响缓存响应时间和吞吐量。 2. 惰性过期: * 描述:只有在访问某个键时才判断其是否过期,过期则清除。 * 优点:最大化节省 CPU 资源。 * 缺点:可能会有大量过期键未被访问而占用内
6 min read
Redis数据库——数据结构类型
Redis

Redis数据库——数据结构类型

大家好,这里是编程Cookbook。本文详细介绍Redis 提供的5种基本数据结构类型和4种特殊类型,除此之外,还有8种底层数据结构,每种结构类型有其特点和适用场景。 基本数据类型 1. String(字符串) * 简介:Redis 最基本的数据类型,一个 key 对应一个 value,支持二进制安全,可存储任意数据(如图片、序列化对象)。 * 特点: * 最大可存储 512MB 数据。 * 用于缓存、计数器、分布式 ID 生成等场景。 * 常用命令: * 存储:SET key value、MSET key value [key value ...] * 获取:GET key、MGET key [key ...] * 计数器操作:INCR key、
20 min read
MySQL数据库——常见的几种锁分类
MySQL

MySQL数据库——常见的几种锁分类

大家好,这里是编程Cookbook。本文详细介绍MySQL的几种常见锁分类,如:表级锁、行级锁、页面锁、悲观锁、乐观锁、共享锁、排他锁、Gap-锁等。 按锁粒度分 表级锁 * 开销小,加锁快,不会出现死锁,锁粒度大(整张表)。 * 并发度低,发生锁竞争概率大,适合查询。 行级锁 * 开销大,加锁慢,会出现死锁,锁粒度最小(一行数据)。 * 并发度高,发生锁竞争概率小,适合并发写,事务控制。 页面锁 * 开销、加锁速度、锁粒度、并发度都介于表级锁和行级锁之间,会出现死锁。 总结 很难说哪种锁更好,只能根据具体应用程序的特点选择合适的锁。 * 对于查询远大于修改的场景,表级锁是合适的,因为锁粒度大但管理简单。 * 对于并发查询并发更新少量数据的应用,行级锁是更合适的选择,它提供更高的并发性和灵活性。 InnoDB的默认锁是行级锁,但通过意向锁机制实现了多粒度锁的协同工作。 锁与索引关系
15 min read
MySQL数据库——存储引擎(InnoDB、MyISAM、MEMORY、ARCHIVE)
MySQL

MySQL数据库——存储引擎(InnoDB、MyISAM、MEMORY、ARCHIVE)

大家好,这里是编程Cookbook。本文详细介绍MySQL数据库重要的存储引擎及其适用场景:InnoDB、MyISAM、MEMORY、ARCHIVE。 MySQL的存储引擎(Storage Engine)是用于管理数据存储和数据访问的程序模块。常用的存储引擎有 InnoDB(事务处理和高并发,默认存储引擎)、MyISAM(高查询性能,但不支持事务)、Memory(高速缓存)等。 * InnoDB:适用于大多数业务场景,提供事务、行级锁和外键支持,是MySQL的默认存储引擎。 * MyISAM:适用于读多写少、对事务一致性要求不高的场景。 * MEMORY:适用于需要高速缓存的场景,但数据会在数据库重启时丢失。 * ARCHIVE:适用于存储大量归档数据,不支持更新操作。 * CSV:适用于导出和交换数据的场景,数据以CSV格式存储。 * NDB (Cluster):适用于分布式、高可用性和高扩展性的场景,通常用于MySQL Cluster。 * FEDERATED:适用于跨数据库查询,允许访问远程数据库中的数据。 * BLACKHOLE:适用于数据复制,
11 min read
MySQL数据库——数据库三范式
MySQL

MySQL数据库——数据库三范式

大家好,这里是编程Cookbook。本文简要介绍关系型数据库设计的三范式。 数据库的三范式(3NF)是关系数据库设计中用于减少数据冗余、避免数据异常和提高数据一致性的三种规范化标准。 以下是 第一范式(1NF)、第二范式(2NF) 和 第三范式(3NF) 的详细介绍: 范式 第一范式(1NF) 要求每一列都是不可拆分的原子项。 第二范式(2NF) 第二范式要求属性完全依赖于主键,而不能只依赖于主键的一部分。满足 第一范式 的基础上,解决部分依赖(Partial Dependency)的问题。 * 关系必须满足 第一范式。 * 消除部分依赖:对于复合主键(即由多个列组成的主键),非主属性必须依赖于整个复合主键,而不是依赖于主键的一部分。 订单表中出现业务线,不同业务线的订单价格不同,那么主键就必须是订单id和业务线id(完全依赖)。 第三范式(3NF) 第三范式要求属性直接依赖于主键,不依赖于通过其他非主属性间接依赖于主键。 * 关系必须满足 第二范式。 * 消除传递依赖:任何非主属性都不能通过其他非主属性间接依赖
3 min read