【进阶篇】MySQL的MVCC实现机制详解

文章目录

  • 0.前言
  • 1.基础介绍
    • 1.1. 什么是MVCC?
    • 1.1. 什么是当前读和快照读?
    • 1.1. 当前读,快照读和MVCC的关系
    • 1.1. MVCC能解决什么问题,好处是?
      • 1.1.1. 提高并发性能
      • 1.1.2. 避免死锁
      • 1.1.3. 解决脏读、不可重复读和幻读等问题
      • 1.1.4. 实现非阻塞读
      • 1.1.5. 提供一致性视图
  • 2. MVCC的实现原理
    • 2.1. 隐式字段
    • 2.1. undo日志
      • 场景示例
    • 2.1. Read View(读视图)
      • 基本介绍
      • 场景示例
      • 原理
        • readview如何判断版本链中的哪个版本可用呢?(重点!)
    • 2.1. 整体流程
  • 3. MVCC相关问题
    • 3.1. RR是如何在RC级的基础上解决不可重复读的?
    • 3.1.RC,RR级别下的InnoDB快照读有什么不同?
  • 参考资料

在这里插入图片描述

0.前言

在这里插入图片描述
在数据库领域,对数据进行并发操作是常见的需求。为了保证数据的一致性和事务的隔离性,不同的数据库系统采用了不同的并发控制技术。其中,多版本并发控制(MVCC,Multiversion Concurrency Control)是MySQL中InnoDB存储引擎采用的一种非常重要的并发控制技术。

MVCC通过创建数据在某个时间点的"快照",让事务能够访问到一个一致的数据视图,而不会被其他事务操作影响。这样不仅可以提高并发性能,而且可以避免在读取数据时进行加锁,大大增强了数据库的并发处理能力。

在本篇博客中,我们深入探讨MySQL的MVCC实现机制,包括Undo日志、Read View以及事务链等概念。我们将详解MVCC如何在保证数据一致性的同时,提高数据库的并发处理能力。 理解和掌握MySQL中MVCC的工作原理,以更好地进行数据库设计和优化。

虽然我们的标题是 MySQL的MVCC实现机制详解,大家不要误认为MVCC机制是MySQL独有的。

MVCC 不是MySQL的特有机制,除了MySQL 使用了MVCC机制,其他数据库版本也使用了
以下是一些采用了多版本并发控制(MVCC)策略的数据库:

  1. PostgreSQL:它使用 MVCC 提供多个并发用户间的一致性视图。

  2. MySQL:在可重复读取隔离级别下,MySQL的InnoDB存储引擎利用 MVCC 解决读写冲突,提供快照数据而非最新数据。

  3. Oracle:尽管Oracle使用了MVCC,但其实现方法与PostgreSQL和MySQL的InnoDB不同。在Oracle中,读操作不会阻塞写操作,反之亦然。

  4. SQLite:SQLite使用了"snapshot isolation",它的核心概念与MVCC相似,都是在事务开始时提供一个快照,而非实时数据。

  5. CouchDB 和 MongoDB:这两个NoSQL数据库也采用了MVCC或类似技术。

  6. Apache HBase:作为开源的非关系型分布式数据库,HBase是Google BigTable的Java实现,也使用了MVCC。

  7. Apache Cassandra:这是Facebook开发的一款开源分布式NoSQL数据库系统,用于满足高速读写需求,如Inbox搜索,它也实现了MVCC。

  8. MariaDB:作为MySQL的一个开源分支版本,MariaDB的InnoDB存储引擎也使用了MVCC。

  9. Microsoft SQL Server:在读已提交快照和快照隔离级别下,SQL Server使用了MVCC。

1.基础介绍

1.1. 什么是MVCC?

MVCC,全称是多版本并发控制(Multi-Version Concurrency Control),是一种用来解决数据库并发问题的方法。在高并发的场景下,为了提高性能,采用MVCC是一种比单纯的加锁更有效的方式。

MVCC的工作原理是,每次对数据进行更新操作,都不会直接覆盖原有数据,而是为数据添加一个新的版本。并且,每个事务都可以看到一个一致的快照版本,这个版本在该事务启动时就已经确定。

这样,就可以实现在不阻塞读操作的前提下进行写操作,也就是实现了读写分离,提高了数据库的并发处理能力。

MVCC实现机制主要包括以下几个方面:

  1. 数据版本化:每一条数据都有一个版本号,每次修改数据,都会生成一个新的版本。查询时,只要在版本列表中找到对应的版本即可,而不需要等待数据修改完成。

  2. 读视图:每一次事务开始时,都会生成一个读视图,这个读视图记录了开始该事务时,正在执行的所有其他事务的事务ID。在进行查询操作时,只查询在读视图记录的事务ID之前开始的事务对应的数据版本。

  3. undo日志:在修改数据时,会把修改前的数据版本写入undo日志。如果有其他事务需要访问修改前的数据版本,可以直接从undo日志中获取。

MVCC只在READ COMMITTED和REPEATABLE READ两个隔离级别下工作。在这两个隔离级别下,读操作不会产生任何锁,大大提高了查询性能,降低了锁冲突的概率,从而使得更多的应用可以并发运行。

1.1. 什么是当前读和快照读?

在数据库中,读操作主要分为两种:当前读(Current Read)和快照读(Snapshot Read)。

  1. 当前读:就是读取记录的最新版本,也就是最新的数据。如果数据在读取过程中被其他事务修改了,那么会读取到最新的数据内容。当前读会对读取的数据加锁,阻止其他事务对数据进行修改。当前读主要出现在UPDATE、DELETE、INSERT、SELECT…FOR UPDATE这些需要进行写操作的SQL语句中。

  2. 快照读:读取的是记录在事务开始时的版本,也就是读取快照中的数据。即使在读取过程中数据被其他事务修改,读取到的数据内容也不会改变。快照读不会对读取的数据加锁,不会阻止其他事务对数据进行修改。快照读主要出现在普通的SELECT语句中。

这两种读操作的主要区别在于是否对读取的数据加锁,以及读取的是数据的哪个版本。

1.1. 当前读,快照读和MVCC的关系

当前读和快照读都是MySQL中的读操作,它们的区别在于读取的数据版本和是否加锁。然而,这两种读操作并不能完全满足并发控制的需求。这就是MVCC(多版本并发控制)的作用。

MVCC是一种用于实现事务并发控制的机制。在MVCC中,每次对数据的修改都会创建一个新的数据版本。不同的事务会看到不同版本的数据,这取决于事务开始的时间以及事务的隔离级别。

当进行快照读(非锁定读)时,MVCC允许事务读取一个旧的数据版本。这意味着在同一时间点,不同的事务可以看到同一行数据的不同版本,避免了因等待锁而导致的阻塞。这在幻读(phantom read)和非可重复读(non-repeatable read)这两种情况下特别有用。

当进行当前读(锁定读)时,如UPDATE或SELECT FOR UPDATE,会读取最新版本的数据,并对其加锁以防止其他事务进行修改。

因此,MVCC、当前读和快照读是密切相关的。MVCC通过提供一种机制,使得当前读和快照读能够在并发事务中同时有效地工作,从而提高数据库的整体性能。

1.1. MVCC能解决什么问题,好处是?

1.1.1. 提高并发性能

MVCC允许多个读操作与写操作同时进行,无需等待锁,因此可以大大提高并发性能。

在传统的数据库并发控制中,为了保证数据的一致性,通常会使用锁来阻止其他事务在当前事务完成之前读取或修改数据。这种方式虽然可以保证数据的一致性,但是其并发性能较差,因为读操作和写操作之间存在阻塞。

而在MVCC机制中,对于读操作,系统会创建一个数据版本的快照,而不是直接对数据加锁,这样即使有其他事务正在对数据进行修改,当前事务也可以进行读操作。举例来说,假设我们有一个在线购物系统,当用户A查看某个商品的信息时,即使此时商家正在修改这个商品的价格,用户A也可以正常查看商品信息,不会被阻塞。

对于写操作,MVCC通过生成旧版本数据的拷贝来避免直接修改数据。这样当其他事务需要读取数据时,即使数据已经被修改,也可以通过读取这个旧版本数据的拷贝来获取数据,而不需要等待写操作完成。比如上述在线购物系统中,当商家修改商品价格时,如果此时有用户正在查看这个商品,那么用户看到的仍然是旧的价格,无需等待商家修改价格的操作完成。

1.1.2. 避免死锁

由于读操作不需要加锁,所以减少了产生死锁的可能。

在传统的锁定机制中,如果两个或更多的事务在相互等待对方所持有的锁,就会发生死锁。例如,如果事务A锁定了资源1并试图获得资源2,而事务B已经锁定了资源2并试图获得资源1,那么就会出现死锁,因为每个事务都在等待对方释放其需要的资源。

而在MVCC中,由于读操作不需要加锁,事务可以在不影响其他事务的情况下读取数据。这就意味着读操作不会因为等待其他事务释放锁而被阻塞,从而减少了死锁的可能性。

例如,假设有两个事务,事务A和事务B,它们都需要读取和修改同一条数据。在MVCC中,事务A可以先创建一个数据的快照进行读操作,此时即使事务B也开始修改这条数据,事务A的读操作也不会被阻塞。而当事务A要进行写操作时,只有当事务B的写操作已经完成并且事务已经提交,事务A的写操作才会被阻塞。这样就大大降低了死锁的可能性。

1.1.3. 解决脏读、不可重复读和幻读等问题

通过在每个事务处理其自己的快照,并在需要时创建对象的新版本,MVCC能够解决脏读、不可重复读和幻读等事务隔离问题。
在MVCC(多版本并发控制)模型中,每个事务处理的都是数据库在某个时间点的快照,并且在多个事务处理同一个数据项时,会生成该数据项的新版本。这种机制能有效解决一系列事务隔离的问题:

  1. 脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。在MVCC机制中,每个事务都只读取事务开始时的数据快照,不会读取到其他未提交事务的数据,因此避免了脏读。

  2. 不可重复读:不可重复读是指在一个事务内,多次读同一数据时,由于其他事务的提交,导致多次读取的结果不一致。MVCC通过在每个事务开始时创建数据的快照,并在事务运行过程中一直使用此快照,确保了在同一事务中多次读取同一数据总是返回同一个结果,避免了不可重复读。

  3. 幻读:幻读是指在一个事务内部,先后执行两个查询操作,第二个查询出现了第一个查询不存在的记录,或者之前的记录消失,这种现象称为幻读。可重复读(RR)隔离级别下的InnoDB能通过MVCC来防止幻读,事务会看到一个一致的快照,这个快照在事务开始时创建,并在事务运行期间不会更改,从而避免了幻读。

1.1.4. 实现非阻塞读

在MVCC模型下,读操作不会阻塞写操作,写操作也不会阻塞读操作。

1.1.5. 提供一致性视图

使用MVCC,每个事务都在其开始时获取一个快照,然后在该快照上执行所有操作,这样可以保证事务执行过程中看到的数据是一致的。

2. MVCC的实现原理

2.1. 隐式字段

InnoDB引擎在MVCC实现过程中,会在每行数据后面添加额外的系统隐藏字段;
根据官方文档中描述是三个字段 DB_ROW_IDDB_TRX_IDDB_ROLL_PTR。但是从有的博客文章中看到还有一个字段DELETED_BIT 。我在相关官方文档中没有证实。如果哪位同仁找到官方的相关描述记得@一下我,非常感谢
我在mysql5.7和8.0版本的官方文档和代码里都去求证未果。

  1. 5.7版本 mvcc 官方文档 https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html
  2. 8.0版本 mvcc 官方文档 https://dev.mysql.com/doc/refman/8.0/en/innodb-multi-versioning.html
  3. MySQL源码地址 https://github.com/mysql/mysql-server/tree/8.0
    在这里插入图片描述
    在这里插入图片描述
  • DB_ROW_ID: 6bytes,隐含的自增ID(隐藏主键)。如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引。
  • DB_TRX_ID: 6bytes,最近修改(修改/插入)事务ID。记录创建这条记录或最后一次修改该记录的事务ID。
  • DB_ROLL_PTR: 7bytes,回滚指针。指向这条记录的上一个版本(存储于Undo Log里)。
  • DELETED_BIT: 1byte,【我暂未证实存在,只是在一些博客帖子中看到有同学在解释】该字段标识该行是否被删除。记录被更新或删除,并不意味真的删除,而是删除标志位变更。

通过这种方式,InnoDB存储引擎通过DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID等隐式字段,结合Undo Log,实现了MVCC的功能,同时保证了事务的ACID性质(原子性、一致性、隔离性、持久性)。

2.1. undo日志

Undo日志在MySQL的InnoDB中是用于实现数据一致性、事务回滚以及多版本并发控制(MVCC)的重要组成部分。Undo日志主要由以下几部分组成:

  1. Undo日志记录:每个Undo日志记录包含了一个数据版本的信息。当一个事务对数据库中的某个记录进行修改时,InnoDB会在Undo日志中生成一个包含这个记录修改前信息的Undo日志记录。

  2. Undo日志段(Undo Log Segment):Undo日志记录被分组存储在Undo日志段中。每个事务在开始时会在Undo段中创建一个新的Undo日志记录,这个记录包含了事务开始时候的数据状态。

  3. 回滚段(Rollback Segment):回滚段是Undo日志段的容器,每个回滚段可以包含多个Undo日志段。InnoDB中默认存在128个回滚段。

  4. Undo表空间(Undo Tablespace):Undo表空间是存储Undo日志的物理空间,可以存储多个回滚段。

在InnoDB中,Undo日志的生命周期从事务开始到事务结束。如果一个事务在执行过程中失败或者被显式回滚,InnoDB将使用Undo日志记录来恢复数据的原始状态,确保数据的一致性。如果事务执行成功并提交,相关的Undo日志记录将被标记为可回收,并在之后的清理操作中被删除。

概念和理论相对比较苦涩,我们以商城系统中的商品表为示例。

场景示例

比如有个商品表。
第一步:有个事务插入商品表插入了一条新记录,记录如下,名称为萝卜, price为1,隐式主键是1,事务ID和回滚指针,我们假设为NULL。
第二步:现在来了一个事务1对该记录的name做出了修改,改为黄瓜。
第三步:又来了个事务2修改商品表的同一个记录,将price修改为2.5 。

我们可以推测出 undo日志的存储过程 和表内容变化如下

  1. 商品表的初始状态如下:
名称价格隐式主键事务ID回滚指针
萝卜11NULLNULL
  1. 然后,事务1对名称字段做出了修改。这时,对应的undo日志记录如下:
事务ID表名行ID操作类型旧值新值
1商品表1更新萝卜黄瓜
  1. 商品表的状态变为:
名称价格隐式主键事务ID回滚指针
黄瓜111指向事务1的undo日志
  1. 接着,事务2对价格字段做出了修改。对应的undo日志记录如下:
事务ID表名行ID操作类型旧值新值
2商品表1更新12.5
  1. 商品表的状态变为:
名称价格隐式主键事务ID回滚指针
黄瓜2.512指向事务2的undo日志

这个过程中,InnoDB会为每一次的修改操作生成一条undo日志记录。如果之后需要回滚事务,InnoDB就可以利用这些undo日志记录恢复数据的原始状态。

2.1. Read View(读视图)

基本介绍

Read View或读视图是用来实现一致性非锁定读(即MVCC,多版本并发控制中的读操作)的一种机制。

当一个事务需要执行一致性非锁定读操作时,InnoDB会为该事务生成一个读视图。这个读视图包含了当前正在活动的所有事务的事务ID,这些事务在生成读视图的时间点之后如果有新的数据改动,都不会被该读视图所看到。换句话说,只有在生成读视图时已经提交的事务改动的数据,才会被该读视图看到。

具体来说,当一个事务开始执行SELECT操作时,如果该事务是在READ COMMITTED隔离级别下,那么InnoDB会在每个SELECT语句之前为该事务生成一个新的读视图。如果该事务是在REPEATABLE READ隔离级别下,那么InnoDB只会在事务开始时生成一个读视图,然后在整个事务期间都使用这个读视图。

场景示例

假设我们有一个简单的银行账户表,包含"账户ID"和"余额"两个字段:

账户ID余额
1500
21000
31500

现在,假设我们有两个并发的事务,事务A和事务B。

1. 事务A开始,它想要查看账户1和账户2的余额,所以它执行一个SELECT语句。由于事务A是在REPEATABLE READ隔离级别下执行的,所以InnoDB为它生成一个读视图。这个读视图捕获了数据库在事务A开始时的状态,即账户1的余额为500,账户2的余额为1000

2. 此时,事务B开始,并且它向账户1汇入了100元,然后提交了事务。数据库的实际状态变为了账户1的余额为600,账户2的余额为1000。

3. 事务A再次执行SELECT语句,想要再次查看账户1和账户2的余额。但是,由于事务A在执行SELECT时使用的是在它开始时生成的读视图,所以它看到的账户1的余额仍然是500,账户2的余额仍然是1000,而不是数据库的实际状态。这就是读视图如何实现一致性非锁定读的。

在这个例子中,尽管事务B在事务A执行过程中改变了数据库的状态,但是由于读视图的存在,事务A看到的数据仍然是一致的,不会受到事务B的影响。这就是InnoDB如何通过使用读视图来实现MVCC的。

原理

在一个readview快照中主要包括以下这些字段:
在这里插入图片描述

  1. m_ids:活跃的事务就是指还没有commit的事务。

  2. max_trx_id:例如m_ids中的事务id为(1,2,3),那么下一个应该分配的事务id就是4,max_trx_id就是4。

  3. creator_trx_id:执行select读这个操作的事务的id。

readview如何判断版本链中的哪个版本可用呢?(重点!)

从上到下分别为(1)(2)(3)(4),依次进行解释
在这里插入图片描述

trx_id表示要读取的事务id

(1)如果要读取的事务id等于进行读操作的事务id,说明是我读取我自己创建的记录,那么为什么不可以呢。

(2)如果要读取的事务id小于最小的活跃事务id,说明要读取的事务已经提交,那么可以读取。

(3)max_trx_id表示生成readview时,分配给下一个事务的id,如果要读取的事务id大于max_trx_id,说明该id已经不在该readview版本链中了,故无法访问。

(4)m_ids中存储的是活跃事务的id,如果要读取的事务id不在活跃列表,那么就可以读取,反之不行

通过这种方式,InnoDB可以为每个事务提供一个它自己的一致性视图,这样即使数据库中的数据在事务执行过程中发生了改变,事务看到的数据也会保持一致,不会受到其他事务的影响。从而实现了事务的一致性读,也就是所谓的snapshot(快照)读,这是实现MVCC的关键。

2.1. 整体流程

MySQL的MVCC多版本并发控制主要涉及以下几个步骤:

  1. 事务启动:当一个事务启动并执行第一个操作时,系统会为该事务分配一个唯一的事务ID。

  2. 读操作:在发生读操作时,InnoDB会创建一个Read View(读视图)。这个读视图记录了启动时所有正在执行的事务ID,该事务在执行过程中,只能看到在读视图创建之前已经提交的事务所做的修改,对于在读视图创建之后其他事务所做的修改,该事务是无法看到的。

  3. 写操作:当事务进行写操作时,InnoDB不会直接覆盖旧的数据,而是将旧数据复制一份保存到undo日志中,并生成一个新的版本数据,新的数据上会记录下创建该版本的事务ID。同时,InnoDB还会在多版本链表中插入一个新的版本,链表中的版本按照事务ID从大到小的顺序进行排序。

  4. 事务提交:当事务提交时,系统会将该事务的ID号从全局的活动事务列表中删除。

  5. 版本回收:当系统判断某个版本的数据已经不再需要时(即没有任何一个活动的事务需要访问这个版本的数据),就会回收这个版本的数据以释放存储空间。
    6.整体执行流程 如下
    在这里插入图片描述

3. MVCC相关问题

3.1. RR是如何在RC级的基础上解决不可重复读的?

RC(Read Committed)级别和RR(Repeatable Read)级别是两种常见的事务隔离级别。

在RC级别,每次读取都会读取到该行最新的数据,因此,一个事务在不同时间执行相同的查询,可能会得到不一样的结果,这就是所谓的“不可重复读”。

为了解决RC级别下的“不可重复读”问题,RR级别的事务在开始时会创建一个快照(snapshot),也就是一个数据的副本。在事务进行过程中,即使其他事务修改了数据,由于每次读取都是读取的这个快照,因此在一个事务内,多次读取同一数据,得到的都是一样的结果。

这就是RR级别如何在RC级别的基础上解决不可重复读问题的。这是通过牺牲一定的并发性能,增加了数据一致性。不过在很多场景下,数据一致性比并发性能更加重要,因此RR级别也被广泛使用。

3.1.RC,RR级别下的InnoDB快照读有什么不同?

既然我们已经了解了RC(Read Committed)和RR(Repeatable Read)的差异,那么,这两个隔离级别下的InnoDB快照读又有什么不同呢?
主要的区别在于快照读的创建时间。

  1. 在RC级别下,每一次语句执行之前都会创建一个新的Read View(快照),而无论这个事务执行了多少语句,只要它还在执行,就会持续创建新的Read View。因此,即使在同一事务中,多次读取同一行数据可能会读取到不同版本的数据,即出现“不可重复读”。

  2. 而在RR级别下,只有在事务刚开始执行第一个语句时会创建一个Read View,之后在这个事务中的所有操作,都只会看到这个Read View所代表的数据版本。其他事务在这之后做的修改,对当前事务来说是不可见的,因此在同一事务中,多次读取同一数据总是能够读到相同的结果,即保证了“可重复读”。

  3. RC和RR级别下InnoDB快照读的差异,主要是由RC和RR的隔离级别特性决定的,RR级别相比RC级别提供了更高的数据一致性,但是在并发性能上可能会有所下降。

参考资料

  1. 官方文档:MySQL官方网站提供了关于各种存储引擎的详细文档,包括InnoDB和MyISAM等。https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html

  2. 书籍《高性能MySQL》是一本非常全面的关于MySQL性能优化、架构设计和内部机制的书籍,其中包含了大量关于存储引擎的内容。

  3. 知乎大佬写的 https://zhuanlan.zhihu.com/p/447372441

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/129433.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【unity3D】如何修改相机的默认视角

💗 未来的游戏开发程序媛,现在的努力学习菜鸡 💦本专栏是我关于游戏开发的学习笔记 🈶本篇是unity的如何修改相机的默认视角 如何修改相机的默认视角 Game窗口运行的话视角是这样的: 此时Scene窗口的视角是这样的&…

游戏发行平台都有什么服务和功能?

游戏发行平台通常提供一系列服务和功能,以帮助游戏开发商将游戏推向市场,并为玩家提供游戏。以下是一些常见的游戏发行平台服务和功能: 1、游戏发布 发行平台允许游戏开发商将游戏上传到平台上,以供玩家下载和安装。 2、游戏销售…

qt作业day4

//clock_exercise.cpp#include "clock_timer.h" #include "ui_clock_timer.h"//时间事件处理函数 void Clock_Timer::timerEvent(QTimerEvent *event) {if(event->timerId() time_id){sys_tm QDateTime :: currentDateTime(); // int year sy…

远程恋爱网站部署秘籍——群晖虚拟机助ni秀恩爱

文章目录 前言1. 安装网页运行环境1.1 安装php1.2 安装webstation 2. 下载网页源码文件2.1 访问网站地址并下载压缩包2.2 解压并上传至群辉NAS 3. 配置webstation3.1 配置网页服务3.2 配置网络门户 4. 局域网访问静态网页配置成功5. 使用cpolar发布静态网页,实现公网…

习题练习 C语言(暑期第四弹)

自我小提升! 前言一、数组二、指针运算三、统计每个月兔子的总数四、双指针的应用五、判断指针六、珠玑妙算七、两数之和八、数组下标九、指针十、寻找峰值十一、二级指针十二、大端小端十三、无符号参数十四、数对十五、截取字符串总结 前言 重要的事说三遍&#…

分布式系统常用的模式

分布式系统常用的模式 Ambassador 名称:“大使”模式 介绍:作为应用程序和其他服务的“中间人”,负责应用程序和其他服务之间的通信,包括日志、监控或重试处理等任务。 举例:K8S使用Envoy作为一个“大使”来简化服务…

Docker 搭建Redis 集群之路

前言 搞技术就是动手,动手再动手,实践出真知,毕竟最终是要解决问题的呢,废话不多讲,开搞,主要是为了记录一下,毕竟过程还是有点艰辛呢需求(target) Windows 电脑 装一个虚拟机用虚拟机构造Linux 系统下载Docker 搭建Redis 集群代码交互集群过关斩将 检查电脑是否开启…

初识Kafka

kafka 第一章、初识Kafka 原先: kafka,由LinkedIn公司采用Scala语言开发的一个多分区,多副本,基于Zookeeper协调的分布式消息系统,被捐献给Apache基金会。 现在 分布式流式处理平台。 高吞吐 可持久化 可水平扩展 …

go小知识2

Golang开发新手常犯的50个错误_gezhonglei2007的博客-CSDN博客 一些题目整理,附带大佬的解释 1.go中哪些值不能寻址& 常量(const常量,字面值3.14,字符串“xxx”,函数或方法, map的val值) golang中接…

JVM系列 运行时数据区

系列文章目录 第一章 运行区实验 文章目录 系列文章目录前言一、堆(Heap)1.1、新生代/Young区1.1.1、Eden区1.1.2、Survival区 1.2、年老代(old区) 二、虚拟机栈(Stack)2.1、栈顶缓存技术2.2、溢出2.3、栈…

83 # 静态服务中间件 koa-static 的使用以及实现

静态服务中间件:koa-static 中间件可以决定是否向下执行,如果自己可以处理,那么直接处理完毕结束,如果自己处理不了,next 方法会继续向下执行 新建 public 文件夹,里面添加 index.html、style.css 文件 …

图的学习,深度和广度遍历

一、什么是图 表示“多对多”的关系 包括&#xff1a; 一组顶点&#xff1a;通常用V&#xff08;Vertex&#xff09;表示顶点集合一组边&#xff1a;通常用E&#xff08;Edge&#xff09;表示边的集合 边是顶点对&#xff1a;(v, w)∈E&#xff0c;其中v,w∈V有向边<v, w&…

go开发之个微机器人的二次开发

简要描述&#xff1a; 设置某条朋友圈为隐私 请求URL&#xff1a; http://域名地址/snsSetAsPrivacy 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名…

CFTC可能比SEC更可怕,将监管炮口直接对准DeFi?

还未开始享受Uniswap在法庭上为DeFi行业带来的“胜利果实”&#xff0c;美国商品期货委员会&#xff08;CFTC&#xff09;在一个星期之后立即将其无情砸碎&#xff0c;并将其监管大炮直接对准了DeFi衍生品市场&#xff0c;乃至整个DeFi行业。 2023年9月7日&#xff0c;CFTC宣布…

leetcode 215.数组中第k大的元素

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;数组中第k大的元素 思路&#xff1a; 使用堆数据结构&#xff0c;大堆的堆顶是堆内最大的元素&#xff0c;也就是把当前堆 pop k - 1 次&#xff0c;第 k 次 top 出来的元素就是第 k 大的数。 代码&#xff1a; class …

Spring-MVC使用JSR303及拦截器,增强网络隐私安全

目录 一、JSR303 ( 1 ) 是什么 ( 2 ) 作用 ( 3 ) 常用注解 ( 4 ) 入门使用 二、拦截器 2.1 是什么 2.2 拦截器与过滤器的区别 2.3 应用场景 2.4 基础使用 2.5 用户登录权限控制 给我们带来的收获 一、JSR303 ( 1 ) 是什么 JSR 303是Java规范请求&#xff…

LeetCode 1126.查询活跃业务

数据准备 Create table If Not Exists Events (business_id int, event_type varchar(10), occurences int); Truncate table Events; insert into Events (business_id, event_type, occurences) values (1, reviews, 7); insert into Events (business_id, event_type, occu…

职场新人对测试用例的困惑

职场新人对测试用例的困惑无非有以下几点&#xff1a; 什么是测试用例&#xff0c;为什么要写测试用例&#xff1f; 不知道怎么写&#xff0c;写了也不知道写的是否完整。 一、什么是测试用例&#xff1f; 百科的释义&#xff1a; 测试用例是对一项特定的软件产品进行测试任…

【CSS系列】writing-mode —— 文字方向(水平/垂直;左右/右左)

文章目录 一、引子二、writing-mode1.语法horizontal-tb&#xff08;默认&#xff1a;水平方向&#xff0c;文字 从左到右&#xff0c;行 从上到下&#xff09;vertical-rl&#xff08;垂直方向&#xff0c;文字 从上到下&#xff0c;行 从右到左&#xff09;vertical-lr&#…

数字化转型背景下企业知识管理能力提升路径

近年来&#xff0c;科技不断进步&#xff0c;颠覆性技术&#xff08;例如 5G、云计算、物联网、大数据分析和人工智能等&#xff09;正在重新定义企业如何管理项目和运营效率。知识管理体系亦需要随着科技的进步而改变&#xff0c;以适应新的数字时代环境&#xff0c;并且高效知…