自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Mysql原理浅析——事务理论

InnoDB使用MVCC来支持高并发,并且实现了四个标准的隔离级别。间隙锁使得InnoDB不仅仅锁定查询的行,还会对索引中的间隙进行锁定以防止幻影行的插入。(2)InnoDB的MVCC,是通过在每行记录后保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存了行的过期时间,当然存储的并不是实际的时间值,而是系统的版本号。每开始一个新的事务,系统版本号都会自动递增。(1)MVCC是行级锁的一个变种,但是他在很多情况下避免了加锁操作,因此开销更低。

2022-09-17 10:34:37 354

原创 Mysql原理浅析——高性能索引策略

可以使用 count(DISTINCT column) / count( * )获得完整列的索引选择性,再通过count(DISTINCT LEFT(7)) / count( * )获得前缀索引的选择性。有时候需要索引很长的字符列,这会导致索引变得大且慢,此时除了可以使用伪hash索引(即使用CRC32函数取得其冗余校验码保存)还可以使用前缀索引,即创建索引时只截取固定字符作为索引。即如果一个索引包含要查询的所有数据,就称之为覆盖索引。通常认为将选择性最高的列放到联合索引的最前列是有助于提高索引效率的。

2022-09-10 10:35:24 492

转载 深入并发编程——缓存伪共享问题

Cache Line 是【已失效】状态,另外由于 1 号核心的 Cache 也有此相同的数据,且状态为【已修改】,所以要先把 1 号核心的 Cache 对应的 Cache Line 写回到内存中,然后 2 号核心再从内存中读取 Cache Line 大小的数据到 Cache 中,最后把变量修改到 2 号核心的 Cache 中,并将状态修改为【已修改】状态。CPU 从内存中读取数据到 Cache 的时候,并不是一个字节一个字节读取,而是一块一块的方式来读取数据的,这一块一块的数据被称为 CPU Line。

2022-09-08 16:06:03 338

原创 深入Redis原理与应用——Redis中的集群

如果一个集群中半数以上的主节点都认为一个节点为疑似下线,则会将其标记为下线,将节点标记为下线的节点会向集群广播一条关于此主节点下线的消息,所有收到这条消息的节点也会将其标记为已下线。(1)一个 redis 集群通常由多个节点组成,刚开始的时候每个节点都是独立的,为了组件一个可工作的集群,必须将各个独立的节点连接起来,构成一个包含多节点的集群。(1)客户端通过发送 CLUESTER MEET 命令和节点 B 的信息给节点 A,收到命令的节点 A 将与节点 B 进行握手,并依次来确认彼此的存在。

2022-09-07 12:42:11 431

原创 深入Redis原理与应用——哨兵模式Sentinel

(1)由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器及其下属的所有从服务器,当主服务器下线后自动将主服务器的某个从服务器升级称为新的主服务器。首先会挑选 server1 属下的一个从服务器并将其升级为新的主服务器。之后 sentinel 系统会向 server1 属下的所有从服务器发送新的复制指令让他们称为新的主服务器的从服务器。sentinel 会继续监视下线的 server1,使其上线后作为新的主服务器的从服务器。

2022-09-07 11:13:14 367

原创 深入Redis原理与应用——主从复制

(2)建立套接字连接:设置完 IP 和端口后从服务器会创建连向主服务器的套接字连接,如果连接成功从服务器会为这个套接字创建一个专门用于复制操作的文件事件处理器,将负责后续的复制工作。在同步操作之前只有从服务器是主服务器的客户端;同步操作之后主服务器也会称为从服务器的客户端(完整重同步发送缓冲区中的命令,部分重同步发送复制积压缓冲区中的数据都需要主是从的客户端)。(4)旧版命令传播:同步之后为了继续保持主从一致,主服务器会将导致主从不一致的命令发送给从服务器,让从服务器执行。(1)检测主从服务器的网络状态。

2022-09-06 23:42:44 141

原创 深入Redis原理与应用——Redis中的服务端

(3)初始化服务器的数据结构:在 initServerConfig 函数中只创建了命令表一个数据结构,然而服务器还需要其它数据结构,比如 server.clients 链表(记录了与服务器相连的每个客户端的状态)、server.db 数组(包含了服务器的所有数据库)等等。(1)发送的命令请求来自 redis 客户端,当用户在客户端中键入一个命令时,客户端会将这个命令请求转换成协议格式,然后通过连接到服务器的套接字将协议格式的命令请求发送给服务器。该函数复制管理服务器的资源并保持服务器自身的良好运转。

2022-09-06 22:21:36 324

原创 深入Redis原理与应用——Redis中的客户端

服务器从协议内容中分析得出 argv 属性和 argc 属性的值之后,服务器将根据 argv[0]的值在命令表(是一个字典,key 为 set、get 等各种操作,值为 redisCommand 格式的处理函数)中查找命令所对应的实现函数,找到后将客户端的 cmd 属性指向这个结构。(2)关闭:客户端可能因客户端进程退出、客户端发送了不符合协议的命令请求、客户端发送的命令过大或要发送给客户端的回复过大等都会导致客户端退出。(5)输出缓冲区:分为固定大小的输出缓冲区和可变大小的输出缓冲区。

2022-09-06 21:48:17 594

原创 深入Redis原理与应用——Redis中的事件

当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)关闭(close)等操作时,与之相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。尽管多个文件事件可能会并发地出现,但 IO 多路复用程序总是会将所有产生事件的套接字都放到一个队列里面然后通过这个队列以有序、同步、每次一个套接字的方式向文件事件分派器传送套接字,上一个套接字传输的事件处理完后才会接着处理下一个。时间事件的处理时间通常比设定的到达时间晚一点。

2022-09-06 21:35:09 404

原创 深入Redis原理与应用——Redis的数据持久化

(2)AOF 持久化功能可以分为命令追加(服务器每执行完一个写命令都会将写命令追加到aof_buf 缓冲区的末尾)、文件写入和文件同步(服务器每结束一个事件循环都考虑是否将aof_buf 缓冲区中的内容同步到 AOF 文件中,具体服务器的设置有 always,everysec 和 no,默认 everysec)(写入和同步的区别是在调用 write 函数写入文件之前还有一个缓冲区缓冲区满了才真正写入,而同步则是强制将缓冲区数据写入文件中)三个步骤。(5)服务器载入 RDB 文件时将一直处于阻塞状态。

2022-09-06 21:16:28 309

原创 深入Redis原理与应用——数据库杂论

(1)服务器中的所有数据库都保存在 redisServer 结构的 db 数组中,db 数组的每一项都是一个 redisDb 结构。dbnum 属性值由服务器配置决定,其决定了数据库的数量。(2)redisClient 中的 redisDb 类型的 db 指针指向了当前选择的数据库。(3)数据库的键空间:因为 redis 是一个键值对数据库服务器,服务器中的每个数据库都由一个 redisDb 结构表示,其中 redisDb 中的 dict 字典保存了所有的键值对,称之为键空间。

2022-09-06 20:50:47 303

原创 深入Redis原理与应用——Redis 中的对象类型

(1)redis 并未直接使用基本数据结构而是基于基本的数据结构封装了对象系统,包括了字符串对象、列表对象、哈希对象、集合对象和有序集合对象。(2)使用对象的好处是可以才不同的场景对对象设置不同的数据结构实现从而优化效率。(3)redis 对象机制使用了基于引用计数的回收机制,当程序不再使用某个对象时该对象就会自动释放,同时也通过引用计数实现了共享机制,节约内存。(4)redis 带有访问时间记录信息,当开启 maxmemory 时空转时长较大的将会优先被删除。

2022-09-06 20:42:09 928

原创 深入Redis原理与应用——Redis 中的基本数据结构

(4)压缩列表节点的属性有 previous_entry_length(可以为 1 字节或 5 字节,表示前一个节点的长度,程序可以通过指针运算逆序查找),encoding(长度可以为 1 字节两字节或五字节,00、01、10 开头分别表示 1 字节长度、2 字节长度和 5 字节长度的字节数组,由于前两位保存了状态所以才有前面的 2 的 6 次方和 2 的 14 次方,注意 5 字节的数组第一个字节只用到前两位保存状态,长度数据只使用后 4 个字节;这是因为(负载因子即使用的节点数处以槽的数量)。

2022-09-06 16:41:45 300

原创 深入理解JVM——类加载机制

从概念上讲,这些变量所使用的内存都应当在方法区中进行分配,但是要注意方法区本身是一个逻辑上的区域,在 JDK7 及之前,HotSpot 使用永久代来实现方法区时,实现是完全符合这种逻辑概念的,但在 JDK8 及之后,类变量会随着 Class 对象一起存放于 Java 堆中,这时候“类变量在方法区”就完全是一种对逻辑概念的表述了。在加载过程中,由于元数据验证,字节码验证的需要,又可能触发其他相关类的加载动作,例如加载这个类的父类或实现的接口。此外,接口的实现类在初始化时也一样不会执行接口的()。

2022-09-05 13:13:32 432

原创 深入理解JVM——内存分配与回收策略

如果允许,那会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行一次 Minor GC,尽管这次 Minor GC 是有风险的;(5)动态对象年龄判定:为了能更好地适应不同程序的内存状况,HotSpot 虚拟机并不是永远要求对象的年龄必须达到设定值才能晋升到老年代,如果在 Survivor 空间中相同年龄所有对象大小的总和大于 Survivor 空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。而当复制对象时,大对象就意味着高额的内存复制开销。...

2022-08-30 21:43:34 250

原创 深入理解JVM——垃圾收集器

各收集器搭配关系:JDK9 之后取消了两款搭配组合优点:简单而高效,是所有收集器里额外内存消耗最小的。对于单核处理器或处理器核心数较少的环境来说,Serial 收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。Serial 收集器对于运行在客户端模式下的虚拟机来说是一个很好的选择(其停顿时间对许多用户来说都是可以接受的)。(1)实质上是 Serial 收集器的多线程并行版本。(2)自 JDK9 开始取消了 ParNew 加 Serial Old 以及 Serial 加 C

2022-08-30 21:39:44 390

原创 深入理解JVM——HotSpot 垃圾回收算法细节实现

在赋值前的部分的写屏障叫作写前屏障,在赋值后的则叫作写后屏障。(3)增量更新破坏的是第一个条件,当黑色对象插入新的指向白色对象的引用关系时,就将这个新插入的引用记录下来,等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象为根,重新扫描一次。(3)应用写屏障后,虚拟机就会为所有赋值操作生成相应的指令,一旦收集器在写屏障中增加了更新卡表操作,无论更新的是不是老年代对新生代对象的引用,每次只要对引用进行更新,就会产生额外的开销,不过这个开销与 Minor GC 时扫描整个老年代的代价相比还是低得多的。...

2022-08-30 20:25:22 513

原创 深入理解JVM——分代收集理论及垃圾收集算法

(3)HotSpot 虚拟机中关注吞吐量的 Parallel Scavenge 收集器是基于标记-整理算法的(如果跟标记-清除算法那样完全不考虑移动和整理存活对象的话,弥散于堆中的存活对象导致的空间碎片化问题就只能依赖更为复杂的内存分配器和内存访问器来解决,势必会直接影响应用程序的吞吐量),而关注延迟的 CMS 收集器则是基于标记-清除算法。(1)将可用的内存按容量分为大小相等的两块,每次只使用其中的一块,当这一块用完后就将还活着的对象复制到另一块上,然后再把已使用过的空间一次清理掉。...

2022-08-30 19:57:00 483

原创 深入理解JVM——GC中判断对象是否存活的算法

(1)在虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆。(5)Java 虚拟机内部的引用,比如基本数据类型对应的 Class 对象,一些常驻的异常对象,还有系统类加载器。在对象中添加一个引用计数器,有地方引用它时计数器值就加 1,引用失效后计数器值就减 1。(4)在本地方法栈中 JNI(即通常所说的 Native 方法)引用的对象。(2)方法区中类静态属性引用的对象,譬如 Java 类的引用类型静态变量。(3)在方法区中常量引用的对象,譬如字符串常量池里的引用。...

2022-08-30 17:31:02 234

原创 Java中的集合类——ConcurrentHashMap

(1)由于HashMap并非线程安全,且HashTable效率低下,故多线程下ConcurrentHashMap为首选。(2)ConcurrentHashMap主要有三大结构:整个Hash表,segment(段),HashEntry(节点)。每个segment就相当于一个HashTable。ConcurrentHashMap主要有三大结构:整个Hash表,segment(段),HashEntry(节点)。每个segment就相当于一个HashTable。...

2022-08-29 19:52:08 592

转载 Java中的集合类——HashMap中的并发死链

e.next = newTable[i] 导致 key(3).next 指向了 key(7)。注意:此时的key(7).next 已经指向了key(3), 环形链表就这样出现了。注意:因为Thread1的 e 指向了key(3),而next指向了key(7),其在线程二rehash后,指向了线程二重组后的链表。(1)假设我们有两个线程。而下一次循环的next = e.next导致了next指向了key(3)。而我们的线程二执行完成了。然后是e = next,导致了e指向了key(7)。(4)环形链接出现。.

2022-08-29 11:22:08 419

原创 Java中的集合类——HashMap

(1)在hash表中进行添加、删除、查找等操作性能很高,不考虑hash冲突的情况下仅需一次定位即可完成,时间复杂度为O(1)。(2)hash表的主干就是数组。(3)当我们要新增或查找某个元素,我们通过把当前元素的关键字通过某个函数映射到数组中的某个位置,通过数组下标一次定位就可完成操作。即:存储位置 = f(关键字)(4)哈希冲突:当我们对某个元素进行哈希运算,得到一个存储地址,然后要进行插入的时候,发现已经被其他元素占用了,其实这就是所谓的哈希冲突,也叫哈希碰撞。...

2022-08-29 10:57:35 1355

原创 深入并发编程——AQS框架

AQS队列同步器(AbstractQueuedSynchronizer),是Java提供的用来构建锁或者其他同步组件的基础框架。它使用了一个int的成员变量表示同步状态,通过内置的FIFO队列(CLH队列)来完成资源获取线程的排队工作。...

2022-08-28 14:52:44 364

原创 深入并发编程——死锁活锁和饥饿

意思是在进程执行之前就申请需要的全部资源,直至所有的资源全部获得后才开始执行,如果有一个资源不能获得,则也不给该进程分配其他的资源。(2)破坏不可剥夺条件:指当某进程获得了部分资源,但得不到其他资源,就释放已获得的资源,但是只适用于内存和处理器资源。(3)破坏循环等待条件:给系统的所有资源编号,规定进程所请求的资源顺序必须按照资源的编号依次进行。(2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(3)不可剥夺条件:进程获得的资源,在未完全使用完之前不能强行剥夺。......

2022-08-26 21:27:05 263

原创 深入并发编程——共享模型之管程(悲观锁)

(2)其它线程使用该对象使偏向锁升级为轻量级锁(注意此时的条件是有多个线程使用共享资源但是没有产生竞争,即虽然多个线程访问了共享资源但是使用时间是叫错开的,如果没有交错开发生了竞争则会直接进入重量级锁阶段,因为竞争的线程需要队列阻塞),即Thread0 当给一个对象加了偏向锁后,Thread1 在其运行结束使用共享资源,就会将偏向状态改为不可偏向,MarkWord 后三位由 101 设为 001,前面的偏向线程信息置为 0。Monitor 是操作系统层面的,本身存在很多的 Monitor,初始。...

2022-08-26 21:16:38 515

原创 深入并发编程——线程状态

(4)箭头 3:线程调用 join 方法后,调用 join 的线程会进入 WAITING 状态(注意是调用时所处的线程而不是 join 针对的线程)。(2)RUNNABLE 状态:线程处于运行状态,可运行状态以及阻塞状态(该阻塞状态为操作系统层面的阻塞,如 BIO 读写文件,这时该线程实际不会用到CPU,会导致线程上下文切换,进入阻塞状态)。(2)可运行状态(就绪状态):指该线程已经被创建,已经与操作系统关联,等待 CPU 调度。(3)运行状态:获取了 CPU 时间片正在执行的状态。...

2022-08-26 18:51:08 167

原创 深入并发编程——线程运行原理

当线程上下文切换发生时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态,Java 中对应的概念就是程序计数器,它的作用是记住下一条jvm 指令的执行地址,是线程私有的。(4)运行到某一函数时在虚拟机栈中创建一个新的栈帧,传入参数以及函数内定义的局部变量会存放在局部变量表中,局部变量表在栈帧创建时就会将相关内存分配好。(3)在虚拟机栈中创建 main 函数的栈帧,栈帧中包括局部变量表,返回地址,锁记录,操作数栈等。(2)每个线程只能有一个活动栈帧,对应着当前正在执行的方法。...

2022-08-26 18:36:47 223

原创 深入理解JVM——浅析HotSpot中的对象

jvm中的对象

2022-08-15 17:54:51 413

原创 深入理解JVM——了解JAVA运行时数据区

java虚拟机的运行时数据区

2022-08-15 16:50:11 307

空空如也

空空如也

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

TA关注的人

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