自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(38)
  • 问答 (1)
  • 收藏
  • 关注

原创 缓存雪崩、缓存击穿、缓存穿透

我们每次往数据库写入数据时,计算该数据的N个哈希函数值,然后分别与布隆过滤器(一个位图数组)的长度取模,得到位图上的编号,接着,这N个编号上的值置为1,这样后面查询数据是否在布隆过滤器,就可以对数据同样求N个哈希值,看看N个编号上是否都是1,是则说明数据库。在进行业务操作的时候,如果缓存和布隆过滤器中都判断不存在这个数据,那么证明这个数据一定不存在于数据库,那么,就可以不用去数据库查找数据了。缓存雪崩和缓存击穿都可通过查询数据库进行缓存重构,但是缓存穿透就不一样了,它是缓存中没有数据,数据库中也没有数据。

2023-09-27 22:43:06 262

原创 Redis的哨兵机制

一个哨兵判断某个节点“主观下线”后,会通知其它哨兵对该节点的存活状态做出判断,只有规定数量quorum (一般是哨兵数量 / 2 + 1)的哨兵认为该节点下线,该节点才会被哨兵标记为“客观下线”配置文件中有一个down-after-milliseconds * 10的配置项,如果主从节点在down-after-milliseconds时间内没有连接上,就可以认为主从节点断连了,而一旦这种情况超过十次,就说明这个从节点的网络状况不好,不适合作为新的主节点。主节点是否存活,如果主节点挂了,他会从从节点中。

2023-09-27 22:42:33 438

原创 主从复制是怎么实现的?

当从服务器与主服务器断开TCP连接时,主服务器就无法向从服务器继续进行写操作的命令传播,这时,为了保证主从数据的一致性,Redis2.8之前,采用的方法是,在从服务器与主服务器重连之后,直接进行全量复制,但是,由于从服务器其实本身之前可能已经同步了一部分数据,这时再清空进行全量复制,开销就太大了。Redis提供了主从复制模式,将数据备份到多台服务器上,较好地保证数据的丢失,同时,一台服务器故障后,其它服务器还能够提供服务。主服务器要与许多的从服务器进行全量复制时,主服务器会不停的忙于fork子进程。

2023-09-26 22:52:36 747

原创 Redis过期删除策略和内存淘汰策略的区别

循环中每次从过期字典中抽取20个key检查是否过期,如果过期则删除,同时记录本轮20个key中过期的key的数量expired,循环检查完20个key后判断expired是否操作检查的key的25%,超过则进入下一检查。然后,再按照一定的概率对logc进行增加,logc值越大的key,越难再增加。Redis不是采用传统的LRU算法,而是在每个对象结构体中包含了一个额外字段,记录了这个对象的最后一次访问时间,这样,在进行内存淘汰的时候,直接随机抽取5(默认)个对象,然后淘汰最久没有使用的那个。

2023-09-25 19:01:48 247

原创 Redis大key对持久化的影响

总的来说是两方面:一方面策略在的情况下执行写指令会直接写入磁盘,在写入大key时,会阻塞主进程较长时间另一方面,都会由主进程fork出一个子进程,这样在遇到大key的情况下,和的时候,都会造成主进程的阻塞。

2023-09-24 13:13:12 49

原创 RDB快照

值得注意的是,子进程执行RDB快照的过程中,如果父进程对和子进程共享的数据(已经存在的键值对)进行了修改,由于写时复制技术(具体可以参见AOF持久化),父进程修改的物理内存会被复制一份出来给子进程,然后父进程再修改它的那份数据,而这时和AOF持久化不同的地方来了,父进程修改的键值对在子进程中,还是原来的数据,RDB持久化的时候,RDB文件中记录的还是旧的数据。写时复制还有个极端的情况,就是如果子进程执行快照期间,如果主进程修改了所有数据,那么所有的共享数据在内存中就会被复制一份,也就是。

2023-09-24 13:10:51 47

原创 AOF持久化

其实,在AOF重写的过程中,Redis执行完一条写命令后,会同时将它放到AOF缓冲区和AOFC重写缓冲区,子进程完成AOF的重写操作,就是将其内存中的键值对一个个转换成一条条命令后,写入新的AOF文件中,会向主进程发送一个异步信号,主进程接收到信号后就会调用一个信号处理函数,其中,会做两件事,一个是将AOF缓冲区中的内容追加到新的AOF文件中(使得新的AOF保持的是最新的数据库状态),然后再将新的AOF文件改名覆盖原来的AOF文件。这样,重写完成后,就会用新的AOF文件覆盖旧的AOF文件。

2023-09-24 13:09:35 43

原创 MySQL三个日志的作用

使得MySQL有crash-safe的能力。redo log记录了事务执行过程中的修改操作,如果事务提交后MySQL奔溃,重启后可以通过redo log来使数据恢复到最新状态。另外,还使得数据的写操作从随机写变成顺序写。因为redo log是追加写,不同于直接对数据在磁盘上进行的写操作,那样需要在磁盘找到对应的记录,是随机写的。

2023-09-15 20:38:03 63

原创 MySQL有哪些锁?

上面出现了两个会话向同一张表同时执行insert语句的情况,因此,可能出现sessionB执行批量插入语句获得主键1,2,接着sessionA执行插入语句获得主键3,然后sessionB继续执行插入语句获得主键4,5,因此,最后sessionB的insert语句,生成的id不连续。但是无论哪个先记录,最后binlog拿去从库执行,由于从库会按照顺序执行,只有执行完一条语句才会执行下一条,因此执行sessionB的insert语句,生成的id是连续的,这时,就会出现主从数据不一致的情况。

2023-09-08 16:38:54 29

原创 MySQL有哪些锁?

上面出现了两个会话向同一张表同时执行insert语句的情况,因此,可能出现sessionB执行批量插入语句获得主键1,2,接着sessionA执行插入语句获得主键3,然后sessionB继续执行插入语句获得主键4,5,因此,最后sessionB的insert语句,生成的id不连续。但是无论哪个先记录,最后binlog拿去从库执行,由于从库会按照顺序执行,只有执行完一条语句才会执行下一条,因此执行sessionB的insert语句,生成的id是连续的,这时,就会出现主从数据不一致的情况。

2023-09-06 22:41:50 37

原创 可重复读级别下,还可能出现的幻读情况?

当A事务开启事务后进行查询id为xxx比如5的记录,发现不存在这条记录,但是另一个B事务开启然后插入了一条id为5的记录并提交。for update,它们也是当前读。这样,A事务更新id为5的记录后,由于事务自己更新的记录自己总是可见,因此当A事务再次查询时会发现这次能够查到id为5的记录了。事务A开启后执行一条快照读查询id为5的记录发现不存在,然后另一个事务B开启然后插入一条id为5的记录并提交,接着A事务通过当前读再次查询发现可以查到id为5的记录。

2023-08-27 21:50:16 401

原创 事务的隔离级别怎么实现的?

读未提交:一个事务还没提交,它所做的变更就能被其它事务看到读提交:一个事务提交之后,它所做的变更才能被其它事务看到可重复读(MySQL默认事务隔离级别):一个事务执行过程中看到的数据和这个事务启动时看到的数据是一样的,只有当前事务提交之后重新开启,才能看到最新的数据串行化:对记录加上读写锁,当多个事务对该记录进行读写操作时,如果发生读写冲突,后访问的事务必须等待前一个事务完成,才能继续执行读提交之上解决了读未提交的问题可重复读之上解决了不可重复读和读未提交的问题,很多程度解决幻读问题。

2023-08-24 21:16:17 80

原创 count()和count(1)的区别?

性能由大到小:count(*) = count(1) > 遍历二级索引的count(索引字段) > 遍历 主键索引的count(索引字段) > count(普通字段)

2023-08-22 21:36:27 40

原创 索引什么时候会失效?

因为联合索引的B+树的排序规则是,先按照最左的第一列的字段排序,第一列数据相同时,才会按照第二列的字段排序。所以,为了尽可能地使用到联合索引中更多的列,我们where条件中的列必须是从联合索引中最左边的列开始连续的列(当然,其实有查询优化器的存在,只要最左边的列存在,则会走索引,至于使用到多少个字段,就要看where条件中是否包含其它列了)当我们再添加一个age字段,不过age字段没有建立索引,这个时候因为不满足最左匹配原则并且查询的字段并不都包含在二级索引当中,这个时候就会走全表扫描。

2023-08-22 20:37:50 36

原创 索引什么时候会失效?

因为联合索引的B+树的排序规则是,先按照最左的第一列的字段排序,第一列数据相同时,才会按照第二列的字段排序。所以,为了尽可能地使用到联合索引中更多的列,我们where条件中的列必须是从联合索引中最左边的列开始连续的列(当然,其实有查询优化器的存在,只要最左边的列存在,则会走索引,至于使用到多少个字段,就要看where条件中是否包含其它列了)上图说明MySQL会隐式地将字符串“10”转换成10,否则,如果将9转换成“9”,两个数字字符串进行比较,从高位至低位比较,这时1 < 9则select结果为0才对。

2023-08-21 21:34:02 40

原创 从数据页的角度看B+树

InnoDB是以数据页为单位来读写数据的,数据页大小默认是16KB,每次从磁盘最少读取16KB的数据到内存,或者刷新内存中16KB的数据到磁盘。InnoDB采用了B+树进行索引,B+树中的每一个节点都是一个数据页。

2023-08-20 21:31:38 41

原创 为什么MySQL采用B+树作为索引?

这样就造成在查找某个节点或者记录的过程中需要更多的磁盘IO去从磁盘读取记录的数据到内存。而且,如果我们采用B树进行范围查询,肯定需要进行中序遍历,但是这也会涉及多个节点的磁盘IO问题。二叉搜索树上每一个节点的左子树上节点的大小都比该节点小,右子树上节点大小都比该节点大。B树则改进了二叉树只有两个分支的问题,它是一个多叉树,每个节点可以有大于2个的节点,这样整个树的高度就得到了下降。,当数据是按照大小顺序插入的时候,插入的时间复杂度为O(N),而我们在检索每一个节点的时候都会涉及一次磁盘IO,也就是会。

2023-08-20 21:30:36 26

原创 索引基础知识

帮助存储引擎快速获取数据的一种数据结构,具体来说,索引是数据的目录就像一本的目录一样。它体现了一种以空间换时间的设计思想。存储引擎:实现了对数据的存储、更新和查询并为数据建立索引。存储引擎有很多,常见的有MyISAM、InnoDB、Mermory。MySQL5.5之后,InnoDB成为默认的存储引擎。

2023-08-19 23:27:02 77

原创 MySQL一行记录是怎么存储的?

区:B+树的每一层上的数据页都是通过双向链表连接起来的,但是他们只是逻辑上相邻,实际物理上并不相邻,这样就会造成我们在进行磁盘查询的时候,会有很多的随机IO,而随机IO是很耗时的。记录行是存放在数据页中的,一个数据页的大小是16KB,也就是16384字节,而一个varchar(n)类型的列最多可以存储65533个字节,一些大对象如blob、text可能存储更大的数据,这时一个数据页可能存不下一行记录,就会发生行溢出,溢出的数据就会存放在溢出页中。页的类型很多,不仅有数据页,也有undo日志页、溢出页等。

2023-08-17 22:24:17 171 1

原创 执行一条select语句期间发生了什么?

在MySQL8.0之前,执行SQL语句的时候,MySQL会先解析SQL语句的第一个字段,如果发现是select查询语句,则会先去查询缓存中查找是否有这题查询语句,查询缓存相当于一个map,k是查询语句,v是查询结果,如果有这个k,则直接返回v。,server层的执行器调用索引查询的接口,存储引擎会去定位符合主键查询条件的第一条记录,然后返回给执行器,执行器判断是否符合查询的条件,符合则直接返回给客户端。存储引擎层负责实现索引数据结构,不同的存储引擎支持的索引类型不同,InnoDB支持的索引类型是B+树。

2023-08-16 20:52:24 85 1

原创 MySQL内存篇

因此,MySQL在加载数据页时,会将其相邻的数据页一起加载进Buffer Pool中,那么这些被提前加载进来的数据页就会被加入LRU链表的头节点,但是,如果这些被提前加载进来的数据页一直没被访问,反而因为占用链表头部区域,会将LRU链表中那些热点数据页淘汰,从而使得缓存命中率大大下降。我们将预读页插入到old区域的头部,将真正要读取的页插入到young区域,old区域中的预读页只有在被使用的时候,才会被移动到young区域头部,而如果old区域的预读页一直没有被访问,就会因为新的预读页插入而被淘汰。

2023-08-15 22:28:38 119 1

原创 黑马点评项目学习笔记--(11)UV统计

PV 与 UV 的比值可以反映出这个网站的用户粘度,也就是平均每个用户点击这个网站的次数是多少。UV 值的大小可能是千万甚至上亿的,直接存储在 Redis 中将十分恐怖,如何解决?同一个用户一天内多次点击页面,只记录一次。只要有用户点击了这个页面,就做记录。

2023-06-19 14:28:31 157 2

原创 黑马点评项目学习笔记--(9)附近商铺

SpringDataRedis的2.3.9版本并不支持Redis6.2提供的GEOSEARCH命令,因此我们需要提示其版本,修改pom.xml。redis在3.2版本后加入了对Geo的支持,Geo就是Geolocation,代表地理坐标。按照shopId作为分类依据,在redis中保存不同类型商铺的地理坐标信息和商铺的id。4.查找某个地点的经纬度信息 / 经纬度信息对应的hash值。3.返回某个坐标点的某个范围内的坐标点(由近及远)转化为 hash 值后可读性更好、存储空间更小。2.计算两点之间的距离。

2023-06-19 14:27:28 88

原创 黑马点评项目学习笔记--(7)达人探店

set和sortedset在命令上有所区别,set有sismember命令判断某个元素是否存在,而sortedset则没有,它只能通过zscore命令(查找某个元素的分数)来帮助我们判断元素是否存在,当元素存在是会返回对应的分数,不存在则返回null。

2023-06-19 14:26:26 121

原创 黑马点评项目学习笔记--(10)用户签到

从最好一次签到的位置向前扫描,直到遇到第一次未签到的为止,计算总的签到次数,就是连续签到天数。实际上,我们可以按月统计用户的签到情况,用位图的方式,0表示未签到,1表示已签到。会发现,如果我们用一张数据库表来保存用户签到的记录,会十分占用内存。让这个二进制数字不断右移,同时让这个二进制数字不断与 1 做与运算。如果我们用数据库表来保存签到记录。

2023-06-19 14:26:04 90

原创 黑马点评项目学习笔记--(8)好友关注

为了采用滚动分页的方式,收件箱我们应该采用sortedset来实现,因为和list相比,他不仅能够保证消息的先后顺序,还可以按照score值进行范围查询,我们只需要每次记录读取的最后一个数据的score值,下一次读取时查询该值之后的score对应的消息即可。为了解决传统分页的问题,我们采用滚动分页的方式,每次记录上一次读取至的数据的位置,然后下一次查询就可以从后面开始查询,避免了重复读取消息的情况。1)修改新增探店笔记的业务,在保存blog到数据库的同时,推送到粉丝的收件箱。

2023-06-19 14:25:00 81

原创 黑马点评项目学习笔记--(6)消息队列

消费者不断从Stream消息队列中取出还未被消费的消息,没有取到就进入下一次循环再次获取消息,取到消息之后,处理消息,处理消息完成后会进行ack,如果在处理消息的过程中出现异常,那么进入catch代码块中,对pending-list中的消息进行处理(也会ack),这个时候如果处理过程还是报异常,会记录日志,必要时进行人工介入,同时会进入下一次循环,直到从pending-list中取不出消息。队列中的消息会分流给组内的不同消费者,在一个组中,不会出现一条消息被多个消费者消费的情况,从而加快消息处理的速度。

2023-06-19 14:22:58 305

原创 黑马点评项目学习笔记--(5)秒杀优化

先利用Redis完成库存余量、一人一单判断,完成抢单业务在将下单业务放入阻塞队列,利用独立线程异步下单。

2023-06-05 17:55:40 277

原创 黑马点评项目学习笔记--(4)分布式锁

满足集群模式或者分布式系统下,多进程可见并且互斥的锁。原理:利用 setnx 的互斥性;利用 ex 避免死锁;释放锁时判断线程标识防止释放别人的锁缺陷:不可重入、无法重试、锁超时失效。

2023-06-05 17:51:03 312

原创 深入浅出--Mysql的三种日志

当write_pos追上check_point时,redo log写满,mysql会被阻塞,此时不能再进行写操作,这时会停下来将buffer pool中的脏页刷新到磁盘,接着,既然脏页中的记录已经落盘,就可以擦除redo中的一些记录,check_point也向后顺时针移动,这样,write_pos与check_point之间就有了可以写入的空间。接着,从库的IO线程会通过连接主库的log dump线程,读取主库的binlog日志并将读取到的数据写入到从库的relay log中继日志中,

2023-05-31 22:52:47 1819 1

原创 黑马点评项目学习笔记--(3)优惠券秒杀

如何以key这样命名,说明订单业务的id自增会一直与这一个key绑定在一起,几年或者十年都是这个key在自增,而reids中单个key自增的上限是2^64,虽然订单量可能无法达到这个数值,但是上图已经规定了,订单编号是用32个bit来存储的,订单数量很可能会超过2^32。redis的kye可以自增长,而且redis是全局中唯一的一个,所以无论数据库中订单在多少个表中,都开始生成一个全局的唯一id。2)订单量庞大时,需要多张表来存储,采用id值自增长的方式,订单id可能不唯一。

2023-05-21 16:52:21 420 1

原创 B+树深入探究

索引可以分为聚集索引与二级索引,它们的区别在于叶子结点存放的是什么数据,对于聚集索引,叶子结点存放的是完整的用户记录,而二级索引中叶子节点存放的是记录的主键。文件头包含两个指针,一个指向上一个数据页,一个指向下一个数据页,连接起来的数据页相当于一个双向链表,这样,数据页不一定需要物理上的连续,只是逻辑上的连续。,将槽指向的记录组的最大记录的主键与查找的记录的主键进行对比,直到查找到记录对应的槽。数据的存储是按照“行”存储的,但是数据库的读取是以“页”的方式。当查找某条记录的时候,会先根据索引键大小,采用。

2023-05-21 12:10:01 52 1

原创 黑马点评项目学习笔记--(2)商户查询缓存

而在查询数据库与写入缓存期间,B线程过来进行更新数据库与删除缓存的操作,A线程再进行写入缓存的操作,这样一来,缓存中保存的是旧数据,而数据库保存最新数据,从而出现数据不一致。一个线程在操作缓存与操作数据库期间,另一个线程恰好过来查询缓存并进行写入操作,这样一来,缓存保存的是旧数据,而数据库是最新的记录,从而出现数据不一致。发生概率:一方面,A线程进行查询缓存操作时缓存得恰好失效,另一方面,因为写入缓存的速度很快,在如此快的时间内完成更新数据库(耗时)、删除缓存的操作,比如店铺详情查询的缓存。

2023-05-15 10:42:22 133 1

原创 黑马点评项目学习笔记--(1)短信登录

用户登录成功后,之后的操作都会涉及到登录状态的验证,起初,第一次验证时,由于每次发起的请求中包含cookie,而cookie中携带了sessionId,系统会根据sessionId获取到session对象,然后看看session中是否包存在用户,存在时,不会立刻放行,而是把用户保存在ThreadLocal(相当于缓存)中,方便之后登录校验,可以直接从threadLocal中取。首先要对用户提交的手机号进行验证合法性,合法了,才会生成一个验证码保存在session中,接着,才会发送验证码到用户手机中。

2023-05-12 11:33:55 345

原创 分布式版本控制系统Git入门

每个用户的电脑都是一个完整的版本库,工作的时候不需要联网,一个用户只需要与任意的其它用户互相推送各自的修改,就能够看到对方修改的内容了。用户本地电脑没有历史版本信息,所有历史数据保存在一个中央服务器上,需要通过联网从中央服务器上获取或者更新。3)Repository仓库区(本地仓库):提交的所有历史版本代码,head指向最新放入仓库的版本。从中央服务器拉取最新的数据,然后将自己修改完的数据推送到中央服务器。4)Remote远程仓库:托管代码的服务器,进行远程数据交换。3.git的四个工作区。

2023-05-07 21:24:16 39 1

原创 Mysql5.5在进行数据导入时出现异常?如何升级mysql版本?

Mysql5.5在导入数据的时候可能会出现索引字段过长的情况,导致不支持,需要升级到5.7。3. 复制mysql-5.7.21-winx64的bin路径到path下。2.下载完成会解压,在mysql安装目录下创建my.ini文件。# 服务端使用的字符集默认为8比特编码的latin1字符集。1.到官网下载想要的对应版本的mysql安装包。# 设置mysql数据库的数据的存放目录 (# 创建新表时将使用的默认存储引擎。二、下载要更换的对应版本的mysql。# 设置mysql的安装目录(

2023-05-07 11:31:56 87 1

原创 Mysql事务隔离级别是如何实现的?

Mysql中事务的隔离级别是如何实现的?

2023-05-06 20:39:46 478

原创 Mysql默认的隔离级别“可重复读”是如何解决幻读问题的,完全解决了吗?

mysq的默认隔离级别是如何解决幻读问题的?

2023-05-06 20:29:56 573 1

空空如也

空空如也

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

TA关注的人

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