自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(23)
  • 收藏
  • 关注

原创 关于Redis Cluster集群运维与核心原理

当客户端向一个错误的节点发出了指令,该节当客户端向一个错误的节点发送指令时,该节点会察觉到指令涉及的 key 并不在自己负责的槽位上。客户端接收到这个指令后,不仅会切换到正确的节点执行操作,还会更新本地的槽位映射表缓存,确保后续的所有 key 都使用新的槽位映射表。每个节点都需要被设置成集群模式,这种模式没有中心节点的概念,可以水平扩展,根据官方文档的称述,甚至可以线性扩展到上万个节点(尽管官方推荐不超过 1000 个节点)。它允许数据分布在多个节点上,每个节点都可以对外提供服务,避免了单一主节点的瓶颈。

2024-02-01 21:42:53 934

原创 关于Redis持久化与主从与哨兵架构

哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)此时 Redis 因为故障停机,便可通过 AOF 文件中的记录,将丢失的数据重新加载到 Redis 中,从而减小数据丢失的风险。

2024-01-30 17:12:45 993

原创 关于Redis核心数据结构与高性能原理

I/O 多路复用:Redis 利用 epoll 来实现 I/O 多路复用,意味着主线程可以有效监听多个 socket,将连接信息和事件放入队列,依次放入文件事件分派器,事件分派器将事件分发给事件处理器,但每个连接的具体处理(例如命令解析和执行)仍然由主线程串行进行。多线程 I/O:为了进一步提高性能,尤其是面对大量连接但每个连接数据交换量不大的场景,Redis 6.0 引入了多线程负责解析网络请求,使主线程专注于命令的执行,即可更好利用现代多核处理器的能力,减少网络延迟的影响。

2024-01-25 23:57:07 923

原创 关于Spring底层原理整体脉络

AOP 即为进行动态代理,在创建一个 Bean 的过程中,Spring 在最后一步会去判断当前正在创建的这个 Bean 是否需要进行AOP,若需要则会进行动态代理。当某个方法上加 @Transactional 注解后,就表示该方法在调用时会开启 Spring 事务,而此方法所在的类所对应的 Bean 对象会是该类的代理对象。因此从 Spring 容器得到 UserService 的 Bean 对象时,实际上得到的是 UserServiceProxy 所生成的对象,即代理对象。

2023-08-13 16:28:29 270

原创 关于由浅入深理解并发、线程与等待通知机制

用户线程也称为协程,内核线程的切换开销是来自于保护和恢复现场的成本,若改为采用用户线程,这部分开销仍然无法避免。不过若将保护、恢复现场及调度的工作从操作系统交到程序员手上,则可以通过很多手段来缩减这些开销。由于最初多数的用户线程是被设计成协同式调度(Cooperative Scheduling),所以才有此别名为“协程”(Coroutine)。其完整地做调用栈的保护、恢复工作,所以现今也被称为“有栈协程”(Stackfull Coroutine)。

2023-07-31 00:42:29 1706

原创 关于InnoDB底层原理与MySQL日志机制

若数据库之前没有备份,但所有的 binlog 日志都在,此时只需从 binlog 第一个文件开始逐个恢复每个 binlog 文件里的数据即可,但这种过于理想化,因为 binlog 日志比较大,早期的 binlog 文件一般会定期删除,因此很难依靠 binlog 文件来恢复整个数据库。主要包括连接器、查询缓存、词法分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,例如存储过程、触发器、视图等。

2023-06-26 00:38:27 819

原创 关于MySQL锁机制与优化实践与MVCC底层原理

因为在 RR 隔离级别下,需要解决不可重复读和幻读问题,所以在遍历扫描聚集索引记录时,为了防止扫描过的索引被其他事务修改(不可重复读问题) 或间隙被其他事务插入记录(幻读问题),从而导致数据不一致,所以 MySQL 的解决方案就是将所有扫描过的索引记录和间隙都上锁,但此时并不是直接将整张表加表锁,因为不一定能加上表锁,可能会有其他事务锁住了表里的其他行记录。假设未提交的事务 id 有 100 和 100,此时未提交事务的 id 数组即为 [100, 200],还存在一个已提交的事务 id 为 300;

2023-05-23 23:59:26 689

原创 关于MySQL事务原理与优化

数据库一般都会并发执行多个事务,多个事务可能会并发地对相同的一批数据进行增删改查操作,由此则引发脏写、脏读、不可重复读、幻读等问题。这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、锁机制、MVCC 多版本并发控制隔离机制、日志机制,用一整套机制来解决多事务并发问题。

2023-05-17 01:18:02 473

原创 关于MySQL索引优化实战

1、MySQL 支持两种方式的排序 filesort 和 index,Using index 是指 MySQL 扫描索引本身完成排序。index 效率高,filesort 效率低。2、order by 满足两种情况会使用 Using index。1) order by 语句使用索引最左前缀法则。2) 使用 where 子句与 order by 子句条件列组合满足索引最左前缀法则。3、尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最左前缀法则。

2023-05-14 18:24:04 1176

原创 关于Explain详解与索引实践

1)id列:id 列的编号是 select 的序列号,有几个 select 就有几个 id,且 id 的顺序是按 select 出现的顺序增长的。id 列越大执行优先级越高,id 相同则从上往下执行,id 为 NULL 则最后执行。2)select_type列:select_type 表示对应行是简单还是复杂的查询。3)table列:表示explain的一行正在访问哪个表。当 from 子句中有子查询时,table列是 格式,表示当前查询依赖id=N的查询,所以会先执行id=N的查询。

2023-05-05 21:41:23 2266

原创 加减乘除计算工具类

加减乘除计算工具类

2023-02-11 15:10:48 195

原创 关于MySQL索引底层数据结构与算法

0x56为Alice对应的磁盘文件地址,例如查询name为Alice时,会先通过hash运算得到结果桶2,再去遍历桶2的链表,最终查询到Alice,包括所对应的磁盘文件地址。根据最左前缀原则,若比较大小会看比较name,若相等,则比较age,若再相等,则比较position,再根据叶子节点存储的主键进行回表查找对应的主键数据。③若不使用自增主键,则在加入新的数据时,可能会多次将数据插入到前面已经放满索引元素的节点,使其进行分裂调整,甚至会导致整棵树重新进行平衡,极大降低效率。实现了自平衡的二叉排序树。

2022-11-29 23:26:42 871 2

原创 关于深入理解AQS之独占锁ReentrantLock

java.util.concurrent 包中的大多数同步器实现都是围绕着共同的基础行为,如等待队列、条件队列、独占获取、共享获取等,而这些行为的抽象就是基于 **AbstractQueuedSynchronizer(简称AQS)**实现的,AQS 是一个抽象同步框架,可用来实现一个依赖状态的同步器。管程:一般使用 MESA,其中有两个队列:①同步等待队列(即上图的入口等待队列,获取锁有关,获取锁失败的线程会加入此队列),②条件等待队列(阻塞唤醒机制)

2022-11-20 01:12:44 408

原创 关于深入理解并发锁机制之synchronized

从偏向锁的加锁解锁过程中可看出,当只有一个线程反复进入同步块时,偏向锁带来的性能开销基本可以忽略,但当有其他线程尝试获得锁时,就需要等到 safe point(即)时,再将偏向锁撤销为无锁状态或升级为轻量级,会消耗一定的性能,所以在多线程竞争频繁的情况下,偏向锁不仅不能提高性能,反而降低性能。因此才有了批量重偏向与批量撤销的机制。批量重偏向和批量撤销是针对类的优化,和对象无关。偏向锁重偏向一次之后不可再次重偏向。

2022-11-14 17:55:17 147

原创 关于CAS与Atomic原子操作

CAS(Compare And Swap,比较并交换),通常指的是这样一种原子操作:针对一个变量,首先比较它的内存值与某个期望值是否相同,如果相同,就给它赋一个新值。CAS 可以看作是它们合并后的整体——一个不可分割的原子操作,并且其原子性是直接在硬件层面得到保障的。CAS可以看做是乐观锁(对比数据库的悲观、乐观锁)的一种实现方式,Java原子类中的递增操作就通过CAS自旋实现的。CAS是一种无锁算法,在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。在并发编程中很容易出现并发安全的问题,举个很

2022-11-10 23:12:38 690

原创 关于深入理解Java线程

程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理IO的 。当一个程序被运行,从磁盘加载此程序的代码到内存时,就开启了一个进程。进程可视为程序的一个实例。大部分程序可同时运行多个实例进程(如记事本、画图、浏览器等),也有的程序只能启动一个实例进程(如网易云音乐、360 安全卫士等)。操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。线程是进程中

2022-11-07 13:07:04 1347

原创 关于深入理解JMM与并发三大特征

Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,以此来实现Java程序在各种平台下都能达到一致的并发效果。JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何及何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步地访问共享变量。JMM描述的是一种抽象的概念,一组规则,通过这组规则控制程序中各个变量在共享数据区域和私有数据区域的访问方式,JMM是围绕原子性、有序性、可见性展开的。

2022-10-31 23:13:28 618

原创 关于垃圾收集器ZGC的扩展

为了满足不同的业务需求,Java 的 GC 算法也在不停迭代,对于特定的应用,选择其最适合的 GC 算法,才能更高效的帮助业务实现其业务目标。对于这些延迟敏感的应用来说,GC 停顿已经成为阻碍 Java 广泛应用的一大顽疾,需要更适合的 GC 算法以满足这些业务的需求。近些年来,服务器的性能越来越强劲,各种应用可使用的堆内存也越来越大,常见的堆大小从10G到百G级别,部分机型甚至可以到达TB级别,在这类大堆应用上,传统的GC,如CMS、G1的停顿时间也跟随着堆大小的增长而同步增加,即堆大小指数级增长时,停

2022-10-29 22:21:45 350

原创 关于垃圾收集器G1与ZGC

G1(Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多个处理器及大容量内存的机器,以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能的特征。G1将Java堆划分为多个大小相等的独立区域(Region),JVM最多可有2048个Region。一般Region大小等于堆大小除以2048,如对大小为4096M,则Region大小为2M。-XX:G1HeapRegionSize:手动指定Region大小,推荐不指定,使用默认计算方式。G1保留年轻代和老年代的概念,但不再使用物理隔阂,

2022-10-28 23:07:53 3006

原创 关于垃圾收集算法与垃圾收集器ParNew与CMS

当前虚拟机的垃圾收集均采分代收集算法,根据对象存活周期的不同将内存分为几块。Java堆分为老年代和年轻代,可根据各自特点选择合适的垃圾收集算法。例如年轻代中,每次收集都会有大量对象被回收,所以可选择复制算法,只需付出少量对象的复制成本便可完成每次的垃圾收集。老年代中,对象存活几率比较高,且没有额外空间对其进行分配担保,因此必须选择标记-清除算法或标记-整理算法进行垃圾收集。标记-清除 或 标记-整理 比 复制算法 慢10倍以上。复制算法,标记-清除算法、标记-整理算法

2022-10-15 00:30:51 1724

原创 关于JVM对象创建与内存分配机制

1. 类加载检查:当虚拟机接收到一条new指令时,会先检查这个指令的参数是否能在常量池中定位出一个类的符号引用,并且检查此符号引用指代的类是否已被加载、解析和初始化,若没有,则执行类加载过程。2. 分配内存:类加载检查通过后,虚拟机将为新生对象分配内存。对象所需内存大小在类加载完成后便以确定,为对象分配空间的任务相当于将一块同等大小的内存从Java堆中划分出来。3. 初始化:虚拟机将分配到的内存空间初始化为零值(不包括对象头),若使用TLAB,此工作过程即可提前到TLAB分配时进行。4. 设置对象头虚拟机需

2022-10-08 14:18:09 1279

原创 关于JVM整体结构

一、线程栈:当运行main方法时便会启动主线程,此时会在栈内开辟一块独立内存空间供其使用,即线程栈,用来存放内部局部变量。局部变量表:存放方法内部的局部变量。操作数栈:存放具体的值,即字面量。动态链接:当程序执行到符号时(例如compute方法),会将compute方法的符号引用替换成直接引用,即指向compute方法内部的代码指令加载到方法区的常量池内所生成的内存地址。方法出口:存放方法结束位置的信息,当方法结束之后根据此信息继续往下执行代码。例如compute方法执行完毕之后会找到结束位置,继续往下执行

2022-10-08 14:12:40 167

原创 关于从JDK源码剖析JVM类加载机制

需继承 ClassLoader;两大核心方法:①loadClass(String, boolean),实现了双亲委派机制;②,默认实现为空方法,需进行重写try {// defineClass 将一个字节数组转为 Class 对象,此字节数组是 class 文件读取后最终的字节数组 return defineClass(name , data , 0 , data . length);

2022-10-08 12:40:05 682 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除