获得徽章 0
#青训营 x 字节后端训练营# 沸点打卡第30天
redis的缓存常见问题
首先是缓存穿透问题,就是服务器到来大量访问,但是所请求的数据在redis中未命中,或者这些数据本就是错误请求,此时会导致大量访问转移到数据库,会导致数据库崩溃。解决方案可以是对空值缓存,即访问空值直接返回默认值,也可以设置访问黑名单(主要对付黑客攻击),还可以设置实时监控,以及布隆过滤器。
其次是缓存击穿问题,即服务器对某一个key到来大量访问,而这个key恰好过期了,此时所有访问集中到数据库导致崩溃。解决方案就是预设热门数据并加大其保持时长,也可以实时监控访问情况并人工调整,还可以设置锁但是会导致性能下降。
然后是缓存雪崩问题,即redis多个key同时过期,此时导致多个访问未命中从而去请求数据库导致崩溃。解决方案可以构建多级缓存、也可以使用锁或者队列,或者设置过期标志来自动更新缓存,也可以在设置过期时间时分散设置。
redis的缓存常见问题
首先是缓存穿透问题,就是服务器到来大量访问,但是所请求的数据在redis中未命中,或者这些数据本就是错误请求,此时会导致大量访问转移到数据库,会导致数据库崩溃。解决方案可以是对空值缓存,即访问空值直接返回默认值,也可以设置访问黑名单(主要对付黑客攻击),还可以设置实时监控,以及布隆过滤器。
其次是缓存击穿问题,即服务器对某一个key到来大量访问,而这个key恰好过期了,此时所有访问集中到数据库导致崩溃。解决方案就是预设热门数据并加大其保持时长,也可以实时监控访问情况并人工调整,还可以设置锁但是会导致性能下降。
然后是缓存雪崩问题,即redis多个key同时过期,此时导致多个访问未命中从而去请求数据库导致崩溃。解决方案可以构建多级缓存、也可以使用锁或者队列,或者设置过期标志来自动更新缓存,也可以在设置过期时间时分散设置。
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第29天
InnoDB为什么用B+树而不是B树?
磁盘访问优化:B+树相较于B树,在磁盘访问方面具有更好的性能。B+树的内部节点不存储具体的数据记录,只存储键值信息和子节点的指针。而B树的内部节点除了存储键值信息,还存储对应的数据记录。因此,B+树的内部节点可以容纳更多的键值信息,减少了树的层级,从而减少了磁盘I/O次数,提高了查询效率。
范围查询优化:B+树在范围查询方面更加高效。由于B+树的叶子节点之间有链表连接,可以方便地支持范围查询和按序遍历。而B树的内部节点也存储数据记录,范围查询时需要在树的内部节点之间进行跳跃,效率相对较低。
顺序访问性能:B+树更适合进行顺序访问,因为它的叶子节点之间有链表连接。这对于范围查询、批量插入和顺序遍历等操作非常重要。
数据索引和存储分离:InnoDB使用B+树作为索引结构,将数据存储在聚簇索引中,聚簇索引的叶子节点即存储了完整的数据记录。而其他的辅助索引则使用B+树的叶子节点指向聚簇索引的叶子节点,实现了索引和数据的分离。这样可以降低索引的维护成本,提高查询效率。
InnoDB为什么用B+树而不是B树?
磁盘访问优化:B+树相较于B树,在磁盘访问方面具有更好的性能。B+树的内部节点不存储具体的数据记录,只存储键值信息和子节点的指针。而B树的内部节点除了存储键值信息,还存储对应的数据记录。因此,B+树的内部节点可以容纳更多的键值信息,减少了树的层级,从而减少了磁盘I/O次数,提高了查询效率。
范围查询优化:B+树在范围查询方面更加高效。由于B+树的叶子节点之间有链表连接,可以方便地支持范围查询和按序遍历。而B树的内部节点也存储数据记录,范围查询时需要在树的内部节点之间进行跳跃,效率相对较低。
顺序访问性能:B+树更适合进行顺序访问,因为它的叶子节点之间有链表连接。这对于范围查询、批量插入和顺序遍历等操作非常重要。
数据索引和存储分离:InnoDB使用B+树作为索引结构,将数据存储在聚簇索引中,聚簇索引的叶子节点即存储了完整的数据记录。而其他的辅助索引则使用B+树的叶子节点指向聚簇索引的叶子节点,实现了索引和数据的分离。这样可以降低索引的维护成本,提高查询效率。
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第28天
今天看了一下https中tsl的握手过程
首先由客户端向服务器发起https请求,此时携带了第一个随机数,服务器持有自己的私钥,以及CA颁发的数字签名证书,服务器将证书、自己的公钥和第二个随机数发送回给客户端,客户端检查证书后,利用服务器的公钥将自己生成的第三个随机数加密发送回服务器,服务器利用私钥解密后,利用这三个随机数组成会话密钥,并回复ok,此时客户端也利用这三个随机数建立会话密钥,这两个密钥相等,即实现了对称密钥,进行加密通话。
今天看了一下https中tsl的握手过程
首先由客户端向服务器发起https请求,此时携带了第一个随机数,服务器持有自己的私钥,以及CA颁发的数字签名证书,服务器将证书、自己的公钥和第二个随机数发送回给客户端,客户端检查证书后,利用服务器的公钥将自己生成的第三个随机数加密发送回服务器,服务器利用私钥解密后,利用这三个随机数组成会话密钥,并回复ok,此时客户端也利用这三个随机数建立会话密钥,这两个密钥相等,即实现了对称密钥,进行加密通话。
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第27天
今天研究了一下http的协议
分别细分了http1.0、http1.1、http2.0、http3.0和https
从特性上分,1.0和1.1的区别主要在于默认短连接和长连接,1.0默认短连接,每个请求都需要建立tcp连接,比较耗时,默认端口号80
1.1默认长连接,一个tcp可以传输多个请求,并且支持同时传送,默认端口号443
2.0默认采用https,s即ssl/tsl,保密协议,采用对称加密(非对称加密的公钥和私钥效率低),通过数字签名证书进行加密过程,需要tsl握手,2.0支持多路复用,避免了域名分片需要建立新的tcp握手耗费的时间,可以支持多请求,但是会出现头部阻塞的情况。
3.0不采用tcp协议,而是基于udp模拟tcp,与tsl共同组成了quic协议,简化了tcp和tsl握手,实现0-RTT,所以必然是加密传输,同时解决了2.0的头部阻塞问题,极大提高了传输效率。
但是主流仍然采用1.1,一些网站采用了2.0
今天研究了一下http的协议
分别细分了http1.0、http1.1、http2.0、http3.0和https
从特性上分,1.0和1.1的区别主要在于默认短连接和长连接,1.0默认短连接,每个请求都需要建立tcp连接,比较耗时,默认端口号80
1.1默认长连接,一个tcp可以传输多个请求,并且支持同时传送,默认端口号443
2.0默认采用https,s即ssl/tsl,保密协议,采用对称加密(非对称加密的公钥和私钥效率低),通过数字签名证书进行加密过程,需要tsl握手,2.0支持多路复用,避免了域名分片需要建立新的tcp握手耗费的时间,可以支持多请求,但是会出现头部阻塞的情况。
3.0不采用tcp协议,而是基于udp模拟tcp,与tsl共同组成了quic协议,简化了tcp和tsl握手,实现0-RTT,所以必然是加密传输,同时解决了2.0的头部阻塞问题,极大提高了传输效率。
但是主流仍然采用1.1,一些网站采用了2.0
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第26天
技术问题-经典网络模型
经典网络模型包括接入(二层交换机为主)、核心(配置svi接口,核心的主要作用是高速转发,作为汇聚、出口、服务器之间的枢纽)、出口(与核心运行OSPF路由协议,与运营商对接使用ACL拨号)
技术问题-经典网络模型
经典网络模型包括接入(二层交换机为主)、核心(配置svi接口,核心的主要作用是高速转发,作为汇聚、出口、服务器之间的枢纽)、出口(与核心运行OSPF路由协议,与运营商对接使用ACL拨号)
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第25天
前两天突然跑出去旅游了
这两天就没咋学习555
完蛋了打卡也被耽误了看样子是达不到天数了
随便吧!刚刚背了八股,明天接着背八股
!!!
前两天突然跑出去旅游了
这两天就没咋学习555
完蛋了打卡也被耽误了看样子是达不到天数了
随便吧!刚刚背了八股,明天接着背八股
!!!
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第24天
今天继续看项目,用Go实现6.824的mapreduce,后续尝试用c++实现
仔细看了mapreduce的论文,对分布式存储有了一定的了解
今天继续看项目,用Go实现6.824的mapreduce,后续尝试用c++实现
仔细看了mapreduce的论文,对分布式存储有了一定的了解
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第22天
白天忘记打卡了,不知道这条算不算
今天没有读文章,自己跑去搞了搞c++的项目,tmd实在太爽了,熬到现在 准备睡了
哎又要长痘了真烦
白天忘记打卡了,不知道这条算不算
今天没有读文章,自己跑去搞了搞c++的项目,tmd实在太爽了,熬到现在 准备睡了
哎又要长痘了真烦
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第21天
如何保证缓存和数据库的一致性?
首先分析问题,介绍了三级数据L订单数据和支付流水、用户相关数据、支付配置信息
然后介绍了数据存入缓存后的新问题:更新时先更新缓存还是数据库,更新缓存时如横额更新?
然后介绍了四种解决方案,以及三个经典的缓存模式:Cache-Aside,Read-Through/W日特through,Write Behind
如何保证缓存和数据库的一致性?
首先分析问题,介绍了三级数据L订单数据和支付流水、用户相关数据、支付配置信息
然后介绍了数据存入缓存后的新问题:更新时先更新缓存还是数据库,更新缓存时如横额更新?
然后介绍了四种解决方案,以及三个经典的缓存模式:Cache-Aside,Read-Through/W日特through,Write Behind
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第20天
常用的分布式事务解决方案
数据库能实现本地事务,也就是在同一个数据库中,你可以允许一组操作要么全都正确执行,要么全都不执行。但现在的系统往往采用微服务架构,业务系统拥有独立的数据库,因此就出现了跨多个数据库的事务需求,这种事务即为“分布式事务”。
接下来介绍了事务概念即ACID四大特性,之后介绍了事务并发执行可能出现的问题,以及四种隔离级别,然后介绍了分布式事务的CAP理论和BASE理论。
之后介绍了分布式事务的协议,两阶段提交协议2PC,三阶段提交协议3PC
最后详细介绍了分布式事务的解决方案:全局事务、基于可靠消息服务的分布式事务、最大努力通知、和TCC
常用的分布式事务解决方案
数据库能实现本地事务,也就是在同一个数据库中,你可以允许一组操作要么全都正确执行,要么全都不执行。但现在的系统往往采用微服务架构,业务系统拥有独立的数据库,因此就出现了跨多个数据库的事务需求,这种事务即为“分布式事务”。
接下来介绍了事务概念即ACID四大特性,之后介绍了事务并发执行可能出现的问题,以及四种隔离级别,然后介绍了分布式事务的CAP理论和BASE理论。
之后介绍了分布式事务的协议,两阶段提交协议2PC,三阶段提交协议3PC
最后详细介绍了分布式事务的解决方案:全局事务、基于可靠消息服务的分布式事务、最大努力通知、和TCC
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第19天
再有人问你分布式事务,把这篇扔给他
文章首先介绍了事务的概念,即将一个活动涉及的所有操作纳入到一个不可分割的执行单元
其特点就是组成事务的所有操作只有在所有操作均能正常执行的情况下方能提交,只要其中任一操作执行失败,都将导致整个事务的回滚。
然后介绍了数据库事务的四大特性ACID,即原子性,一致性,隔离性,持久性
之后介绍了InnoDB引擎的实现原理
然后介绍了分布式事务,即事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
然后介绍了分布式事务的CAP定理,即一致性、可用性、分区容错性。以及BASE,即基本可用、软状态、最终一致性,是对AP的拓展
最后介绍了几种分布式事务常见的解决方案2PC、TCC、本地消息表,MQ、Saga等
再有人问你分布式事务,把这篇扔给他
文章首先介绍了事务的概念,即将一个活动涉及的所有操作纳入到一个不可分割的执行单元
其特点就是组成事务的所有操作只有在所有操作均能正常执行的情况下方能提交,只要其中任一操作执行失败,都将导致整个事务的回滚。
然后介绍了数据库事务的四大特性ACID,即原子性,一致性,隔离性,持久性
之后介绍了InnoDB引擎的实现原理
然后介绍了分布式事务,即事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
然后介绍了分布式事务的CAP定理,即一致性、可用性、分区容错性。以及BASE,即基本可用、软状态、最终一致性,是对AP的拓展
最后介绍了几种分布式事务常见的解决方案2PC、TCC、本地消息表,MQ、Saga等
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第18天
为了拿捏 Redis 数据结构,我画了 40 张图(完整版)
首先介绍了redis快的原因:它是内存数据库,使得所有的操作都在内存上进行之外,还有一个重要因素,它实现的数据结构,使得我们对数据进行增删查改操作时,Redis 能高效的处理。
然后介绍了redis的9种数据结构SDS、双向链表、压缩列表、哈希表、跳表、整数集合、quicklist、listpack。
重点学习了SDS、压缩列表、调表、listpack
为了拿捏 Redis 数据结构,我画了 40 张图(完整版)
首先介绍了redis快的原因:它是内存数据库,使得所有的操作都在内存上进行之外,还有一个重要因素,它实现的数据结构,使得我们对数据进行增删查改操作时,Redis 能高效的处理。
然后介绍了redis的9种数据结构SDS、双向链表、压缩列表、哈希表、跳表、整数集合、quicklist、listpack。
重点学习了SDS、压缩列表、调表、listpack
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第17天
种限流算法,7种限流方式,挡住突发流量?
限流就是对请求或并发数进行限制;通过对一个时间窗口内的请求量进行限制来保障系统的正常运行。
阈值:在一个单位时间内允许的请求量。如 QPS 限制为10,说明 1 秒内最多接受 10 次请求。
拒绝策略:超过阈值的请求的拒绝策略,常见的拒绝策略有直接拒绝、排队等待等。
固定窗口算法又叫计数器算法,是一种简单方便的限流算法。主要通过一个支持原子操作的计数器来累计 1 秒内的请求次数,当 1 秒内计数达到限流阈值时触发拒绝策略。每过 1 秒,计数器重置为 0 开始重新计数。
之后介绍了最常听说的滑动窗口算法
然后是滑动日志算法,基本逻辑就是记录下所有的请求时间点,新请求到来时先判断最近指定时间范围内的请求数量是否超过指定阈值,由此来确定是否达到限流,这种方式没有了时间窗口突变的问题,限流比较准确,但是因为要记录下每次请求的时间点,所以占用的内存较多。
之后又介绍了漏桶算法、令牌桶算法和Redis中的固定窗口限流和滑动窗口限流
窗口算法实现简单,逻辑清晰,可以很直观的得到当前的 QPS 情况,但是会有时间窗口的临界突变问题,而且不像桶一样有队列可以缓冲。
桶算法虽然稍微复杂,不好统计 QPS 情况,但是桶算法也有优势所在。 漏桶模式消费速率恒定,可以很好的保护自身系统,可以对流量进行整形,但是面对突发流量不能快速响应。
令牌桶模式可以面对突发流量,但是启动时会有缓慢加速的过程,不过常见的开源工具中已经对此优化。
上面演示的基于代码形式的窗口算法和桶算法限流都适用于单机限流,如果需要分布式限流可以结合注册中心、负载均衡计算每个服务的限流阈值,但这样会降低一定精度,如果对精度要求不是太高,可以使用。
而 Redis 的限流,由于 Redis 的单机性,本身就可以用于分布式限流。使用 Redis 可以实现各种可以用于限流算法,如果觉得麻烦也可以使用开源工具如 redisson,已经封装了基于 Redis 的限流。
种限流算法,7种限流方式,挡住突发流量?
限流就是对请求或并发数进行限制;通过对一个时间窗口内的请求量进行限制来保障系统的正常运行。
阈值:在一个单位时间内允许的请求量。如 QPS 限制为10,说明 1 秒内最多接受 10 次请求。
拒绝策略:超过阈值的请求的拒绝策略,常见的拒绝策略有直接拒绝、排队等待等。
固定窗口算法又叫计数器算法,是一种简单方便的限流算法。主要通过一个支持原子操作的计数器来累计 1 秒内的请求次数,当 1 秒内计数达到限流阈值时触发拒绝策略。每过 1 秒,计数器重置为 0 开始重新计数。
之后介绍了最常听说的滑动窗口算法
然后是滑动日志算法,基本逻辑就是记录下所有的请求时间点,新请求到来时先判断最近指定时间范围内的请求数量是否超过指定阈值,由此来确定是否达到限流,这种方式没有了时间窗口突变的问题,限流比较准确,但是因为要记录下每次请求的时间点,所以占用的内存较多。
之后又介绍了漏桶算法、令牌桶算法和Redis中的固定窗口限流和滑动窗口限流
窗口算法实现简单,逻辑清晰,可以很直观的得到当前的 QPS 情况,但是会有时间窗口的临界突变问题,而且不像桶一样有队列可以缓冲。
桶算法虽然稍微复杂,不好统计 QPS 情况,但是桶算法也有优势所在。 漏桶模式消费速率恒定,可以很好的保护自身系统,可以对流量进行整形,但是面对突发流量不能快速响应。
令牌桶模式可以面对突发流量,但是启动时会有缓慢加速的过程,不过常见的开源工具中已经对此优化。
上面演示的基于代码形式的窗口算法和桶算法限流都适用于单机限流,如果需要分布式限流可以结合注册中心、负载均衡计算每个服务的限流阈值,但这样会降低一定精度,如果对精度要求不是太高,可以使用。
而 Redis 的限流,由于 Redis 的单机性,本身就可以用于分布式限流。使用 Redis 可以实现各种可以用于限流算法,如果觉得麻烦也可以使用开源工具如 redisson,已经封装了基于 Redis 的限流。
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第16天
一份给算法新人们的「动态规划」讲解
从算法逐步优化角度而言,动态规划更多是从如下方式进行演化:
暴力递归 -> 记忆化搜索 -> 动态规划。
甚至可以说几乎所有的「动态规划」都可以通过「暴力递归」转换而来,前提是该问题是一个“无后效性”问题。
从对“个例”的朴素枚举做法,演变为对“集合”的枚举做法。
所谓的“无后效性”是指当某阶段的状态一旦确定,此后的决策过程和最终结果将不受此前的各种状态所影响。
然后讲解了演进过程的思路,从最开始的暴力递归,到记忆化搜索,即对「暴力递归」过程中的中间结果进行缓存,确保相同的情况只会被计算一次的做法,再到动态规划的三步走,即状态定义、状态转移、初始值计算,只要消除了后效性,就可以保证动态规划的自底向上解决问题。
一份给算法新人们的「动态规划」讲解
从算法逐步优化角度而言,动态规划更多是从如下方式进行演化:
暴力递归 -> 记忆化搜索 -> 动态规划。
甚至可以说几乎所有的「动态规划」都可以通过「暴力递归」转换而来,前提是该问题是一个“无后效性”问题。
从对“个例”的朴素枚举做法,演变为对“集合”的枚举做法。
所谓的“无后效性”是指当某阶段的状态一旦确定,此后的决策过程和最终结果将不受此前的各种状态所影响。
然后讲解了演进过程的思路,从最开始的暴力递归,到记忆化搜索,即对「暴力递归」过程中的中间结果进行缓存,确保相同的情况只会被计算一次的做法,再到动态规划的三步走,即状态定义、状态转移、初始值计算,只要消除了后效性,就可以保证动态规划的自底向上解决问题。
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第15天
分治算法之美
它的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解,可以理解成一种分目标完成程序的算法。
解题步骤:分解:将要解决的问题划分成若干规模较小的同类问题。解决:当子问题划分得足够小时,用较简单的方法解决。合并:按原问题的要求,将子问题的解逐层合并构成原问题的解。
适用特征:把一个问题可以缩小到一定程度,变成更小的问题来解决。分解成若干个小问题后,规模更小且是同类问题,这样子的话,该问题应该就是最优子结构。利用该问题分解出来的子问题的解,合并为该问题的解。分解出来的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
分治算法之美
它的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解,可以理解成一种分目标完成程序的算法。
解题步骤:分解:将要解决的问题划分成若干规模较小的同类问题。解决:当子问题划分得足够小时,用较简单的方法解决。合并:按原问题的要求,将子问题的解逐层合并构成原问题的解。
适用特征:把一个问题可以缩小到一定程度,变成更小的问题来解决。分解成若干个小问题后,规模更小且是同类问题,这样子的话,该问题应该就是最优子结构。利用该问题分解出来的子问题的解,合并为该问题的解。分解出来的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
展开
评论
点赞
#青训营 x 字节后端训练营# 沸点打卡第14天
一张脑图带你看动态规划算法之美
首先简要介绍了DP,即动态规划,是在寻找有很多重叠子问题的情况的最佳解时有效。它将问题重新组合成子问题,为了避免多次解决这些子问题,它们的结果都逐渐被计算并被储存,从简单的问题直到整个问题都被解决。因此,动态规划储存递归时的结果,因而不会在解决同样的问题时花费时间。
简单说就是将一个大的问题拆分成一个个子问题,我们把它称之为子结构。每个最优解,也就是最优值均由[这些小规模子问题]推到而来。更重要的就是利用历史记录,来避免我们重复的计算。
动态规划的三大步骤就是首先进行状态定义,然后列出状态转移方程,最后初始化状态开始dp。
最后介绍了一些dp的分类,如背包dp,线性dp,区间dp,树形dp,数位dp及其例题。
一张脑图带你看动态规划算法之美
首先简要介绍了DP,即动态规划,是在寻找有很多重叠子问题的情况的最佳解时有效。它将问题重新组合成子问题,为了避免多次解决这些子问题,它们的结果都逐渐被计算并被储存,从简单的问题直到整个问题都被解决。因此,动态规划储存递归时的结果,因而不会在解决同样的问题时花费时间。
简单说就是将一个大的问题拆分成一个个子问题,我们把它称之为子结构。每个最优解,也就是最优值均由[这些小规模子问题]推到而来。更重要的就是利用历史记录,来避免我们重复的计算。
动态规划的三大步骤就是首先进行状态定义,然后列出状态转移方程,最后初始化状态开始dp。
最后介绍了一些dp的分类,如背包dp,线性dp,区间dp,树形dp,数位dp及其例题。
展开
评论
点赞