自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Redis总结

在bgsave 的时候,Redis主进程会fork一个子进程,利用操作系统的写时复制技术,这个子进程在拷贝父进程的时候理论上是很快的,因为并不需要全拷贝,比如主进程虽然占了10G内存,但子进程拷贝他可能只要200毫秒,我认为也就阻塞了200毫秒(此耗时基本跟主进程占用的内存是成正比的),这个具体的时间可以通过统计项info stats 里的last_fork_usec查看。实际操作过程是,fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

2023-03-15 20:53:18 184 1

原创 深入浅出Redis之发布与订阅

除了订阅频道之外,客户端还可以通过执行PSUBSCRIBE命令订阅一个或多个模式,从而成为这些模式的订阅者:每当有其他客户端向某个频道发送消息时,消息不仅会被发送给这个频道的所有订阅者,它还会被发送给所有与这个频道相匹配的模式的订阅者。通过执行SUBSCRIBE命令,客户端可以订阅一个或多个频道,从而成为这些频道的订阅者( subscriber ):每当有其他客户端向被订阅的频道发送消息( message)时,频道的所有订阅者都会收到这条消息。将消息发送给频道订阅者。将消息发送个模式订阅者。

2023-03-15 20:50:33 131

原创 深入浅出Redis之集群

如果这时,节点7000进入下线状态,那么集群中仍在正常运作的几个主节点将在节点7000的两个从节点——节点7004和节点7005中选出一个节点作为新的主节点,这个新的主节点将接管原来节点7000负责处理的槽,并继续处理客户端发送的命令请求。,在刚开始的时候,每个节点都是相互独立的,它们都处于一个只包含自己的集群当中,要组建一个真正可工作的集群,我们必须将各个独立的节点连接起来,构成一个包含多个节点的集群。当数据库中的16384个槽都有节点在处理时,集群处于上线状态(ok );

2023-03-15 20:49:11 340

原创 深入浅出Redis之Sentinel

Sentinel(哨岗、哨兵)是Redis的高可用性( high availability )解决方案:由一个或多个Sentinel实例( instance )组成的Sentinel系统( system)可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。如果Sentinel正在监视的是主服务器,那么这些参数记录的就是主服务器的信息;

2023-03-15 20:45:32 252

原创 深入浅出Redis之复制

在同步操作执行完毕之后,主从服务器两者的数据库将达到一致状态,但这种一致并不是一成不变的,每当主服务器执行客户端发送的写命令时,主服务器的数据库就有可能会被修改,并导致主从服务器状态不再一致。在复制操作刚开始的时候,从服务器会成为主服务器的客户端,并通过向主服务器发送命令请求来执行复制步骤,而在复制操作的后期,主从服务器会互相成为对方的客户端。主服务器会将自己执行的写命令,也即是造成主从服务器不一致的那条写命令,发送给从服务器执行,当从服务器执行了相同的写命令之后,主从服务器将再次回到一致状态。

2023-03-15 20:41:08 92

原创 深入浅出Redis之服务器

如果有信号到达,那么表示新的RDB文件已经生成完毕(对于BGSAVE命令来说),或者AOF文件已经重写完毕(对于BGREWRITEAOF命令来说),服务器需要进行相应命令的后续操作,比如用新的RDB文件替换现有的RDB文件,或者用重写后的AOF 文件替换现有的AOF文件。Redis服务器的命令请求来自Redis 客户端,当用户在客户端中键入一个命令请求时,客户端会将这个命令请求转换成协议格式,然后通过连接到服务器的套接字,将协议格式的命令请求发送给服务器,如图14-1所示。3)初始化服务器数据结构;

2023-03-15 20:41:01 483

原创 深入浅出Redis之客户端

如果输出缓冲区的大小超过了软性限制所设置的大小,但还没超过硬性限制,那么服务器将使用客户端状态结构的obuf_soft_limit_reached_time 属性记录下客户端到达软性限制的起始时间;举个例子,假设当前有c1和 c2两个普通客户端正在连接服务器,那么当一个新的普通客户端c3连接到服务器之后,服务器会将c3所对应的客户端状态添加到clients链表的末尾,如图13-12所示,其中用虚线包围的就是服务器为c3新创建的客户端状态。

2023-03-15 20:38:34 118

原创 深入浅出Redis之AOF持久化

当子进程完成创建新AOF文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF 文件重写操作。,所以随着服务器运行时间的流逝,AOF 文件中的内容会越来越多,文件的体积也会越来越大,如果不加以控制的话,体积过大的AOF文件很可能对Redis服务器、甚至整个宿主计算机造成影响,并且AOF 文件的体积越大,使用AOF文件来进行数据还原所需的时间就越多。

2023-03-13 10:30:51 58

原创 深入浅出Redis之事件

服务器不会中途中断事件处理,也不会对事件进行抢占,因此,不管是文件事件的处理器,还是时间事件的处理器,它们都会尽可地减少程序的阻塞时间,并在有需要时主动让出执行权,从而降低造成事件饥饿的可能性。:当一个时间事件到达之后,服务器会根据事件处理器返回的值,对时间事件的 when属性进行更新,让这个事件在一段时间之后再次到达,并以这种方式一直更新并运行下去。随着文件事件的不断执行,时间会逐渐向时间事件所设置的到达时间逼近,并最终来到到达时间,这时服务器就可以开始处理到达的时间事件了。

2023-03-13 10:30:41 196

原创 深入浅出Redis之持久化

例如,如果服务器的0号数据库和3号数据库非空,那么服务器将创建一个如图10-12所示的RDB文件,图中的database 0代表0号数据库中的所有键值对数据,而database 3则代表3号数据库中的所有键值对数据。如果服务器的数据库状态为非空(有至少一个数据库非空),那么这个部分也为非空,根据数据库所保存键值对的数量、类型和内容不同,这个部分的长度也会有所不同。,它的值是一个字符串表示的整数,这个整数记录了RDB文件的版本号,比如"0006"就代表RDB文件的版本为第六版。

2023-03-13 10:29:19 77

原创 深入浅出Redis之对象

ziplist编码的压缩列表对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member ),而第二个元素则保存元素的分值( score )。Redis 共有字符串、列表、哈希、集合、有序集合五种类型的对象,每种类型的对象至少都有两种或以上的编码方式,不同的编码可以在不同的使用场景上优化对象的使用效率。encoding属性记录了对象所使用的编码,也即是说这个对象使用了什么数据结构作为对象的底层实现,这个属性的值可以是表8-3列出的常量的其中一个。

2023-03-13 10:25:59 46

原创 深入千尺Redis之数据库

实现,每当Redis的服务器周期性操作redis.c/serverCron函数执行时,activeExpirecycle函数就会被调用,它在规定的时间内,分多次遍历服务器中的各个数据库,从数据库的expires 字典中随机检查一部分键的过期时间,并删除其中的过期键。:在过期键比较多的情况下,删除过期键这一行为可能会占用相当一部分CPU时间,在内存不紧张但是CPU时间非常紧张的情况下,将CPU时间用在删除和当前任务无关的过期键上,无疑。定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。

2023-03-13 10:25:47 41

原创 深入浅出Redis之对象

ziplist编码的压缩列表对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member ),而第二个元素则保存元素的分值( score )。Redis 共有字符串、列表、哈希、集合、有序集合五种类型的对象,每种类型的对象至少都有两种或以上的编码方式,不同的编码可以在不同的使用场景上优化对象的使用效率。encoding属性记录了对象所使用的编码,也即是说这个对象使用了什么数据结构作为对象的底层实现,这个属性的值可以是表8-3列出的常量的其中一个。

2023-03-13 10:24:03 77

原创 深入浅出Redis之压缩列表

当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。压缩列表是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型( sequential)数据结构。添加新节点到压缩列表,或者从压缩列表中删除节点,可能会引发连锁更新操作,但这种操作出现的几率并不高。一个压缩列表可以包含任意多个节点( entry ),每个节点可以保存一个字节数组或者一个整数值。压缩列表被用作列表键和哈希键的底层实现之一。

2023-03-13 10:22:35 100

原创 深入浅出Redis之整数集合

要让一个数组可以同时保存int16_t、int32_t、int64_t三种类型的值,最简单的做法就是直接使用int64_t类型的数组作为整数集合的底层实现。不过这样一来,即使添加到整数集合里面的都是int16_t类型或者int32_t类型的值,数组都需要使用int64 t类型的空间去保存它们,从而出现。整数集合的底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有需要时,程序会根据新添加元素的类型,改变这个数组的类型。可以保存类型为int16_t、 int32_t或者int64_t的整数值。

2023-03-13 10:21:25 77

原创 深入浅出Redis之跳跃表

Redis 的跳跃表实现由zskiplist和zskiplistNode两个结构组成,其中zskiplist用于保存跳跃表信息(比如表头节点、表尾节点、长度),而zskiplistNode则用于表示跳跃表节点。但通过使用一个zskiplist结构来持有这些节点,程序可以更方便地对整个跳跃表进行处理,比如快速访问跳跃表的表头节点和表尾节点,或者快速地获取跳跃表节点的数量(也即是跳跃表的长度)等信息,如图5-9所示。在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的。

2023-03-13 10:19:44 56

原创 深入浅出Redis之字典

Redis 的哈希表使用链地址法( separate chaining)来解决键冲突,每个哈希表节点都有一个next指针,多个哈希表节点可以用next 指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表连接起来,这就解决了键冲突的问题。举个例子,假设程序要将键值对k2和v2添加到图4-6所示的哈希表里面,并且计算得出k2的索引值为2,那么键k1和k2将产生冲突,而解决冲突的办法就是使用next指针将键k2和k1所在的节点连接起来,如图4-7所示。

2023-03-13 10:18:01 42

原创 深入浅出Redis之简单动态字符串

的惯例,保存空字符的1字节空间不计算在SDS的len属性里面,并且为空字符分配额外的1字节空间,以及添加空字符到字符串末尾等操作,都是由SDS自动完成的作,所以这个空字符对于SDS的使用者来说是完全透明的。虽然SDS的API都是二进制安全的,但它们一样遵循C字符串以空字符结尾的惯例:这些API总会将SDS保存的数据的末尾设置为空字符,并且总会在为buf数组分配空间时多分配一个字节来容纳这个空字符,这是为了让。使用长度为N+1的字符数组来表示长度为N的字符串,并且字符数组的最后一个元素总是空字符‘\0’。

2023-03-10 10:56:43 41

原创 深入浅出Redis之表

在InnoDB存储引擎表中,每张表都有个主键(Primary Key),如果在创建表时。当表中有多个非空唯一索引时,InnoDB存储引擎将选择建表时。索引组织表(index organized table)是否有非空的唯一索引(Unique NOT NULL)InnoDB存储引擎自动创建一个6字节大小的指针。第一个定义的非空唯一索引为主键。表都是根据主键顺序组织存放的。在InnoDB存储引擎中,,如果有,则该列即为主键。,而不是建表时列的顺序。,这种存储方式的表称为。如果不符合上述条件,

2023-03-10 10:48:40 284

原创 Mysql技术内幕之事务

InnoDB是事务的存储引擎,其通过Force Log at Commit机制实现事务的持久性,即当事务提交(COMMIT)时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的COMMIT操作完成才算完成。XA事务允许不同数据库之间的分布式事务,如一台服务器是MySQL数据库的,另一台是Oracle数据库的,又可能还有一台服务器是SQL Server数据库的,只要参与在全局事务中的每个节点都支持XA事务。,除了支持扁平事务支持的操作外,允许在事务执行过程中回滚到同一事务中较早的一个状态。

2023-03-10 10:39:41 47

原创 Mysql技术内幕之性能调优

RAID (Redundant Array of Independent Disks,独立磁盘冗余数组)的基本思想就是把多个相对便宜的硬盘组合起来,成为- -个磁盘数组,使性能达到甚至超过一个价格昂贵、容量巨大的硬盘。由于将多个硬盘组合成为- -个逻辑扇区,RAID 看起来就像一个单独的硬盘或逻辑存储单元,因此操作系统只会把它当作个硬盘。OLTP多用在日常的事物处理应用中,如银行交易、在线商品交易、Blog、 网络游戏等应用。用户首先需要清楚当前数据库的应用类型。不同的文件系统对数据库性能的影响。

2023-03-10 10:39:11 28

原创 Mysql技术内幕之索引与算法

这种merge操作非常类似之前介绍的Insert Buffer 的功能,不同的是Insert Buffer是一个持久的对象,并且其是B+树的结构。B+树的删除操作同样必须保证删除后叶子节点中的记录依然排序,同插入一样,B+树的删除操作同样需要考虑以下表5-2中的三种情况,与插入不同的是,删除根据填充因子的变化来衡量。,key1,key2,…,但是该值还是Index Page中的值,因此在删除Leaf Page中的25后,还应将25的右兄弟节点的28更新到Page Index中,最后可得图5-12。

2023-03-10 10:34:55 91

原创 Mysql技术内幕之锁

但若超时的事务所占权重比较大,如事务操作更新了很多行,占用了较多的undo log,这时采用FIFO的方式,就显得不合适了,因为回滚这个事务的时间相对另一个事务所占用的时间可能会很多。在InnoDB存储引擎中,对于一个外键列,如果没有显式地对这个列加索引,InnoDB存储引擎自动对其加一个索引,因为这样可以避免表锁-—这比Oracle数据库做得好,Oracle数据库不会自动添加索引,用户必须自己手动添加,这也导致了Oracle数据库中可能产生死锁。此外,lock,正如在大多数数据库中一样,是有死锁机制的。

2023-03-10 10:34:38 61

原创 Mysql技术内幕之表

其中 File Header、Page Header、File Trailer的大小是固定的,分别为38、56、8字节,这些空间用来标记该页的一些信息,如 Checksum,数据页所在B+树索引的层数等。比如前面提到的InnoDB 1.0.x版本提供了新的页数据结构来支持表压缩功能,完全的溢出(off page)大变长字符类型字段的存储。,如图4-5所示,在数据页中只存放20个字节的指针,实际的数据都存放在Off Page 中,而之前的Compact和 Redundant两种格式会存放768个前缀字节。

2023-03-10 10:29:48 79

原创 UNIX网络编程详解之select和poll函数

我们遇到的问题是就在客户阻塞于(标准输入上的)fgets调用期间,服务器进程会被杀死。这样的进程需要--种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个IO条件就绪(也就是说输入已准备好被读取,或者描述符已能承接更多的输出),它就通知进程。可以看出,前4种模型的主要区别在于第一阶段,因为它们的第二阶段是一样的:在数据从内核复制到调用者的缓冲区期间,进程阻塞于recvfrom调用。我们将该图分为三个部分:第一部分是处理输入的四个常值,第二部分是处理输出的三个常值,第三部分是处理错误的三个常值。

2023-03-10 10:23:13 96

原创 UNIX网络编程详解之TCP套接字编程

在讨论accept函数时,我们称它的第一个参数为监听套接字(listening socket)描述符(由socket创建,随后用作bind和listen的第一个参数的描述符),称它的返回值为已连接套接字(connected socket)描述符。相反,父进程可以有许多子进程,而且无法获取各个子进程的进程ID。addrlen是值-结果参数(3.3节):调用前,我们将由*addrlen所引用的整数值置为由cliaddr所指的套接字地址结构的长度,返回时,该整数值即为由内核存放在该套接字地址结构内的确切字节数。

2023-03-10 10:21:37 173

原创 UNIX网络编程详解之基本套接字编程

举例来说,如果serv定义为某个网际套接字地址结构,那么serv.sin_addr将按in_addr结构引用其中的32位IPv4地址,而serv.sin_addr.s_addr将按in_addr_t(通常是一个无符号的32位整数)引用同-个32位IPv4地址。在支持长度字段的实现中,sa_family_t通常是一个8位的无符号整数,而在不支持长度字段的实现中,它则是一个16位的无符号整数。对于符合POSIX的实现来说,定义额外的结构字段是可以接受的,这对于网际套接字地址结构来说也是正常的。

2023-03-10 10:19:41 99

原创 UNIX网络编程详解之传输层

我们用粗实线表示通常的客户状态转换,用粗虚线表示通常的服务器状态转换。我们在图中指出,这是由应用进程调用close而发生的,不过需认识到,当- 一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到-一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN。因为SYN占据一个字节的序列号空间,所以每一个SYN的ACK中的确认号就是该SYN的初始序列号加1.类似地,每一个FIN (表示结束)的ACK中的确认号为该FIN的序列号加1。

2023-03-09 11:20:40 80

原创 UNIX网络编程详解之OSI模型

OSI模型

2023-03-09 11:15:59 49

原创 深入浅出高性能Mysql之查询性能优化

如果你希望变量是整数类型,那么最好在初始化的时候就赋值为0,如果希望是浮点型则赋值为0.0,如果希望是字符串则赋值为",用户自定义变量的类型在赋值的时候会改变。MySQL可以通过索引进行排序,当不能使用索引生成排序结果的时候,MySQL需要自己进行排序,如果数据量小则在内存中进行,如果数据量大则需要使用磁盘,MySQL将这个过程统一称为文件排序,即使完全是内存排序不需要任何磁盘文件时也是如此。在5.0之前的版本,是大小写敏感的,所以要注意代码在不同MySQL版本间的兼容性问题。

2023-03-09 11:12:55 381

原创 深入浅出高性能Mysql之创建高性能索引

全文索引是一种特殊类型的索引,它查找的是文本中的关键词,而不是直接比较索引中的值。“独立的列”是指索引列不能是表达式的一部分,也不能是函数的参数。例如,如果在某个选择性很低(哈希冲突很多)的列上建立哈希索引,那么当从表中删除一行时,存储引擎需要遍历对应哈希值的链表中的每一行,找到并删除对应行的引用,冲突越多,代价越大。索引的选择性是指,不重复的索引值(也称为基数,cardinality)和数据表的记录总数(#T)的比值,范围从1/#T到1之间。唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。

2023-03-09 11:09:54 51

原创 深入浅出高性能Mysql之Schema与数据类型优化

选择优化的数据类型 MySQL存储数据的几个简单的原则:更小的通常更好一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为他们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。 简单就好简单数据类型的操作通常需要更少的CPU周期。 尽量避免NULL很多表都包含可为NULL(空值)的列,即使应用程序并不需要保存NULL也是如此,这是因为可为NULL是列的默认属性。通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值。如果查询中包含可为NULL

2023-03-09 11:09:01 111

原创 深入浅出高性能Mysql之Mysql架构

另外,写锁也比读锁有更高的优先级,因此一个写锁请求可能会被插入到读锁队列的前面(写锁可以插入到锁队列中读锁的前面,反之读锁则不能插入到写锁的前面)。这个级别会导致很多问题,从性能上来说,READ UNCOMMITTED不会比其他的级别好太多,但却缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少使用。幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。

2023-03-09 11:05:38 146

原创 深入理解Java并发编程之共享模型无锁

共享模型之无锁

2023-03-09 10:59:33 105

原创 深入理解Java并发编程之共享模型内存

JMM即Java Memory Model,它定义了主存、工作内存抽象概念,底层对应着CPU寄存器、缓存、硬件内存、CPU指令优化等

2023-03-09 10:47:57 69

原创 深入理解Java并发编程之共享模型管程

持obj锁线程的同步代码块执行完毕,会唤醒该对象上所有 BLOCKED的线程重新竞争,如果其中t线程竞争成功,从BLOCKED -->RUNNABLE,其它失败的线程仍然BLOCKED。调用LockSupport.unpark(目标线程)或调用了线程的interrupt(),或是等待超时,会让目标线程从TIMED_WAITING-->RUNNABLE。t线程等待时间超过了n毫秒,或调用obj .notify(), obj .notifyAll(),t.interrupt()时。

2023-03-09 10:40:15 117

原创 深入理解Java并发编程之Java线程

当Context Switch 发生时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态,Java 中对应的概念就是程序计数器( Program Counter Register ),它的作用是记住下一条jvm指令的执行地址,是线程私有的。RUNNABLE当调用了start()方法之后,注意,Java API层面的RUNNABLE状态涵盖了操作系统层面的。(由于BIO导致的线程阻塞,在Java里无法区分,仍然认为是可运行)使用start是启动新的线程,通过新的线程间接执行run中的代码。

2023-03-09 10:31:25 31

原创 深入理解Java并发编程之进程与线程

进程与线程

2023-03-08 14:26:04 40

原创 深入理解JVM之代码执行机制与线程资源同步及交互机制

Java源码编译机制

2023-03-08 10:48:44 133

原创 深入理解JVM之线程安全与锁优化

当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的。

2023-03-08 10:28:48 172

空空如也

空空如也

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

TA关注的人

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