
获得徽章 2
#青训营笔记创作活动#
2月23日 打卡day19
今天学习了高并发场景下缓存存在的问题,以及缓存db数据一致性问题
缓存击穿:数据不在缓存,但在db
缓存穿透:数据既不在缓存,也不在db
缓存雪崩:由于大量key过期或者redis挂掉了,大量请求涌入db,导致db压力过大,甚至宕机。
缓存db数据一致性问题:并发读写,必然存在一致性问题:
缓存中有数据,那么,缓存的数据值需要和数据库中的值相同;
缓存中本身没有数据,那么,数据库中的值必须是最新值。
目前比较好的做法是:
1.旁路缓存 (Facebook的memcached也是这么做的)
2.订阅MySQL的binlog+异步更新
2月23日 打卡day19
今天学习了高并发场景下缓存存在的问题,以及缓存db数据一致性问题
缓存击穿:数据不在缓存,但在db
缓存穿透:数据既不在缓存,也不在db
缓存雪崩:由于大量key过期或者redis挂掉了,大量请求涌入db,导致db压力过大,甚至宕机。
缓存db数据一致性问题:并发读写,必然存在一致性问题:
缓存中有数据,那么,缓存的数据值需要和数据库中的值相同;
缓存中本身没有数据,那么,数据库中的值必须是最新值。
目前比较好的做法是:
1.旁路缓存 (Facebook的memcached也是这么做的)
2.订阅MySQL的binlog+异步更新
展开
评论
点赞
#青训营笔记创作活动#
2月22日 打卡day18
今天学习了使用redis对IP进行限流
获取当前请求的ip和请求的方法
生成key
获取redis中该key的访问次数
判断次数是否超过范围
若超出范围,则拒绝访问,返回提示,并将TTL重置为注解上的等待时间
若没有超过范围,则允许访问,并将访问次数+1
若查询不到该key,则往redis中进行添加,将值设置为1,将TTL设置为注解上的值
2月22日 打卡day18
今天学习了使用redis对IP进行限流
获取当前请求的ip和请求的方法
生成key
获取redis中该key的访问次数
判断次数是否超过范围
若超出范围,则拒绝访问,返回提示,并将TTL重置为注解上的等待时间
若没有超过范围,则允许访问,并将访问次数+1
若查询不到该key,则往redis中进行添加,将值设置为1,将TTL设置为注解上的值
展开
评论
点赞
#青训营笔记创作活动#
2月21日 打卡day17
今天学习了https状态码
HTTP状态码用来表示响应结果的状态,其中200是正常响应,4xx是客户端错误,5xx是服务端错误。
客户端和服务端之间加入nginx,可以起到反向代理和负载均衡的作用,客户端只管向nginx请求数据,并不关心这个请求具体由哪个服务器来处理。
后端服务端应用如果发生崩溃,nginx在访问服务端时会收到服务端返回的RST报文,然后给客户端返回502报错。502并不是服务端应用发出的,而是nginx发出的。因此发生502时,后端服务端很可能没有没有相关的502日志,需要在nginx侧才能看到这条502日志。
2月21日 打卡day17
今天学习了https状态码
HTTP状态码用来表示响应结果的状态,其中200是正常响应,4xx是客户端错误,5xx是服务端错误。
客户端和服务端之间加入nginx,可以起到反向代理和负载均衡的作用,客户端只管向nginx请求数据,并不关心这个请求具体由哪个服务器来处理。
后端服务端应用如果发生崩溃,nginx在访问服务端时会收到服务端返回的RST报文,然后给客户端返回502报错。502并不是服务端应用发出的,而是nginx发出的。因此发生502时,后端服务端很可能没有没有相关的502日志,需要在nginx侧才能看到这条502日志。
展开
评论
点赞
#青训营笔记创作活动#
2月19日 打卡day16
今天学习了TCP,UDP网络协议
TCP面向连接,可靠传输,基于字节流
UDP无连接,不可靠,基于数据报
TCP为了实现可靠性,引入了重传机制、流量控制、滑动窗口、拥塞控制、分段以及乱序重排机制。而UDP则没有实现,因此一般来说TCP比UDP快。
TCP是面向连接的协议,而UDP是无连接的协议。这里的"连接"其实是,操作系统内核在两端代码里维护的一套复杂状态机。
2月19日 打卡day16
今天学习了TCP,UDP网络协议
TCP面向连接,可靠传输,基于字节流
UDP无连接,不可靠,基于数据报
TCP为了实现可靠性,引入了重传机制、流量控制、滑动窗口、拥塞控制、分段以及乱序重排机制。而UDP则没有实现,因此一般来说TCP比UDP快。
TCP是面向连接的协议,而UDP是无连接的协议。这里的"连接"其实是,操作系统内核在两端代码里维护的一套复杂状态机。
展开
评论
点赞
#青训营笔记创作活动#
2月18日 打卡day15
今天学习了redis的一些高级应用。
布隆过滤器是一个很长的二进制向量(位图)和一系列随机映射函数,用于检索一个元素是否在一个集合中
第一步,使用 N 个哈希函数(降低冲突概率)分别对数据做哈希计算,得到 N 个哈希值;
第二步,将第一步得到的 N 个哈希值对位图数组的长度取模,得到每个哈希值在位图数组的对应位置。
第三步,将每个哈希值在位图数组的对应位置的值设置为 1;
查询布隆过滤器说数据存在,并不一定证明数据库中存在这个数据,但是查询到数据不存在,数据库中一定就不存在这个数据
2月18日 打卡day15
今天学习了redis的一些高级应用。
布隆过滤器是一个很长的二进制向量(位图)和一系列随机映射函数,用于检索一个元素是否在一个集合中
第一步,使用 N 个哈希函数(降低冲突概率)分别对数据做哈希计算,得到 N 个哈希值;
第二步,将第一步得到的 N 个哈希值对位图数组的长度取模,得到每个哈希值在位图数组的对应位置。
第三步,将每个哈希值在位图数组的对应位置的值设置为 1;
查询布隆过滤器说数据存在,并不一定证明数据库中存在这个数据,但是查询到数据不存在,数据库中一定就不存在这个数据
展开
评论
点赞
#青训营笔记创作活动#
2月17日 打卡day14
今天学习了db与缓存得一致性问题。
数据库和缓存的数据不一致问题,大都是产生在更新数据时。
在更新的时候,操作缓存和数据库无疑就是以下四种可能之一:
先更新缓存,再更新数据库
先更新数据库,再更新缓存
先删除缓存,再更新数据库
先更新数据库,再删除缓存
在实际业务中,是很重要的一个部分。
2月17日 打卡day14
今天学习了db与缓存得一致性问题。
数据库和缓存的数据不一致问题,大都是产生在更新数据时。
在更新的时候,操作缓存和数据库无疑就是以下四种可能之一:
先更新缓存,再更新数据库
先更新数据库,再更新缓存
先删除缓存,再更新数据库
先更新数据库,再删除缓存
在实际业务中,是很重要的一个部分。
展开
评论
点赞
#青训营笔记创作活动#
2月16日 打卡day13
今天学习WebSocket相关知识
TCP协议本身是全双工的,但我们最常用的HTTP1.1,虽然是基于TCP的协议,但它是半双工的,对于大部分需要服务器主动推送数据到客户端的场景,都不太友好,因此我们需要使用支持全双工的websocket协议。
在HTTP1.1里。只要客户端不问,服务端就不答。基于这样的特点,对于登录页面这样的简单场景,可以使用定时轮询或者长轮询的方式实现服务器推送(comet)的效果。
对于客户端和服务端之间需要频繁交互的复杂场景,比如网页游戏,都可以考虑使用websocket协议。
websocket和socket几乎没有任何关系,只是叫法相似。
2月16日 打卡day13
今天学习WebSocket相关知识
TCP协议本身是全双工的,但我们最常用的HTTP1.1,虽然是基于TCP的协议,但它是半双工的,对于大部分需要服务器主动推送数据到客户端的场景,都不太友好,因此我们需要使用支持全双工的websocket协议。
在HTTP1.1里。只要客户端不问,服务端就不答。基于这样的特点,对于登录页面这样的简单场景,可以使用定时轮询或者长轮询的方式实现服务器推送(comet)的效果。
对于客户端和服务端之间需要频繁交互的复杂场景,比如网页游戏,都可以考虑使用websocket协议。
websocket和socket几乎没有任何关系,只是叫法相似。
展开
评论
点赞
#青训营笔记创作活动#
2月15日 打卡day12
今天学习了线程池。
出于线程管理的需要,线程池应运而生。线程池是一种多线程处理形式,处理过程中将任务提交到线程池,任务的执行交由线程池来管理。使用线程池的好处在于:
降低资源消耗:线程池通常会维护一些线程(数量为 corePoolSize),这些线程被重复使用来执行不同的任务,任务完成后不会销毁。在待处理任务量很大的时候,通过对线程资源的复用,避免了线程的频繁创建与销毁,从而降低了系统资源消耗。
提高响应速度:由于线程池维护了一批 alive 状态的线程,当任务到达时,不需要再创建线程,而是直接由这些线程去执行任务,从而减少了任务的等待时间。
提高线程的可管理性:使用线程池可以对线程进行统一的分配,调优和监控。
2月15日 打卡day12
今天学习了线程池。
出于线程管理的需要,线程池应运而生。线程池是一种多线程处理形式,处理过程中将任务提交到线程池,任务的执行交由线程池来管理。使用线程池的好处在于:
降低资源消耗:线程池通常会维护一些线程(数量为 corePoolSize),这些线程被重复使用来执行不同的任务,任务完成后不会销毁。在待处理任务量很大的时候,通过对线程资源的复用,避免了线程的频繁创建与销毁,从而降低了系统资源消耗。
提高响应速度:由于线程池维护了一批 alive 状态的线程,当任务到达时,不需要再创建线程,而是直接由这些线程去执行任务,从而减少了任务的等待时间。
提高线程的可管理性:使用线程池可以对线程进行统一的分配,调优和监控。
展开
评论
点赞
#青训营笔记创作活动#
2月14日 打卡day11
今天学习了分布式锁。
线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码段。线程锁只在同一JVM中有效果,因为线程锁的实现在根本上是依靠线程之间共享内存实现的,比如synchronized是共享对象头,显示锁Lock是共享某个变量(state)。
进程锁:为了控制同一操作系统中多个进程访问某个共享资源,因为进程具有独立性,各个进程无法访问其他进程的资源,因此无法通过synchronized等线程锁实现进程锁。
分布式锁:当多个进程不在同一个系统中(比如分布式系统中控制共享资源访问),用分布式锁控制多个进程对资源的访问。
基于数据库实现分布式锁基于数据库表(锁表,很少使用)
乐观锁(基于版本号)
悲观锁(基于排它锁)
基于 redis 实现分布式锁: 单个Redis实例:setnx(key,当前时间+过期时间) + Lua
Redis集群模式:Redlock
基于 zookeeper实现分布式锁临时有序节点来实现的分布式锁,Curator
基于 Consul
2月14日 打卡day11
今天学习了分布式锁。
线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码段。线程锁只在同一JVM中有效果,因为线程锁的实现在根本上是依靠线程之间共享内存实现的,比如synchronized是共享对象头,显示锁Lock是共享某个变量(state)。
进程锁:为了控制同一操作系统中多个进程访问某个共享资源,因为进程具有独立性,各个进程无法访问其他进程的资源,因此无法通过synchronized等线程锁实现进程锁。
分布式锁:当多个进程不在同一个系统中(比如分布式系统中控制共享资源访问),用分布式锁控制多个进程对资源的访问。
基于数据库实现分布式锁基于数据库表(锁表,很少使用)
乐观锁(基于版本号)
悲观锁(基于排它锁)
基于 redis 实现分布式锁: 单个Redis实例:setnx(key,当前时间+过期时间) + Lua
Redis集群模式:Redlock
基于 zookeeper实现分布式锁临时有序节点来实现的分布式锁,Curator
基于 Consul
展开
评论
点赞
#青训营笔记创作活动#
2月7日 打卡day10
今天学习了 Java中的线程池。
降低资源消耗。降低频繁创建、销毁线程带来的额外开销,复用已创建线程
降低使用复杂度。将任务的提交和执行进行解耦,我们只需要创建一个线程池,然后往里面提交任务就行,具体执行流程由线程池自己管理,降低使用复杂度
提高线程可管理性。能安全有效的管理线程资源,避免不加限制无限申请造成资源耗尽风险
提高响应速度。任务到达后,直接复用已创建好的线程执行
2月7日 打卡day10
今天学习了 Java中的线程池。
降低资源消耗。降低频繁创建、销毁线程带来的额外开销,复用已创建线程
降低使用复杂度。将任务的提交和执行进行解耦,我们只需要创建一个线程池,然后往里面提交任务就行,具体执行流程由线程池自己管理,降低使用复杂度
提高线程可管理性。能安全有效的管理线程资源,避免不加限制无限申请造成资源耗尽风险
提高响应速度。任务到达后,直接复用已创建好的线程执行
展开
评论
点赞