获得徽章 1
- #青训营笔记创作活动#
2023/2/12
1.什么是Redis
Redis是一个开源的、键值对型的数据存储系统。可以存储多种不同类型值之间的映射,支持事务,持久化,LUA 脚本以及多种集群方案等。
2.Redis的优缺点
优点:
完全基于内存操作,性能极高,读写速度快,Redis 能够支持超过 100KB/s 的读写速率
支持高并发,支持10万级别的并发读写
支持主从模式,支持读写分离与分布式
具有丰富的数据类型与丰富的特性(发布订阅模式)
支持持久化操作,不会丢失数据
缺点:
数据库容量受到物理内存的限制,不能实现海量数据的高性能读写
相比关系型数据库,不支持复杂逻辑查询,且存储结构相对简单
虽然提供持久化能力,但实际更多是一个 disk-backed 功能,与传统意义上的持久化有所区别
3.Redis支持哪些数据类型
String
Hash
List
Set
ZSet
4.Redis中string类型的实现原理
避免缓冲区移除。对字符修改时,可以根据 len 属性检查空间是否满足要求
获取字符串长度的复杂度较低
减少内存分配次数
兼容C字符串函数,可以重用C语言库的一部分函数
5.Redis为何直接以内存存储
Redis 直接以内存的方式存储可以达到最快的读写速度,如果开启了持久化则通过异步的方式将数据写入磁盘,因此Redis 具有快速和数据持久化的特征。
6.Redis如何进行内存优化
1、尽可能使用哈希表(hash 数据结构) :Redis 在储存小于100个字段的Hash结构上,其存储效率是非常高的。
2、根据业务场景,考虑使用 BitMap
3、充分利用共享对象池:Redis 启动时会自动创建【0-9999】的整数对象池,对于 0-9999的内部整数类型的元素,整数值对象都会直接引用整数对象池中的对象,因此尽量使用 0-9999 整数对象可节省内存。
4、合理使用内存回收策略:过期数据清除、expire 设置数据过期时间等
展开评论点赞 - #青训营笔记创作活动#
2023/2/6阅读打卡day9
从其他语言转到Go需要注意的点:
客户端转服务端,最大的挑战不是学一门新语言,而是编程思维的改变;
“三刷”官方文档是我高效学习一门新的编程语言的制胜法宝:
1刷从头看到尾,扫清知识盲点,搞清楚概念;
2刷必须手敲,而且要写注释和总结;
3刷先只写注释,不看文档实现功能,遇到问题再和文档比较,加深理解。如果还有余力,就和我一样整理成文章,分享出来帮助大家学习,回馈社区。
在掌握Go基础之后,也可以通过“三刷”的方式掌握SQL,Redis,Linux,Nginx的基础知识点,这样就有能力开发Web项目了。
要进阶就要学“微服务”和“DDD”
DDD (Domain Driven Design):领域驱动设计:
DDD的核心思想就是避免业务逻辑的复杂性和技术实现的复杂性耦合在一起。
明确业务复杂性和技术复杂性的边界,隔离双方的复杂性,站在更高的角度实现解耦展开评论点赞 - #青训营笔记创作活动#
2023/2/3 阅读打卡day8
什么是跨域问题
1.跨域三种情况:
跨域请求:
协议不同,如 http 和 https;
域名不同;
端口不同。
2.解决跨域问题:
在 Spring Boot 中跨域问题有很多种解决方案,比如以下 5 个:
使用 @CrossOrigin 注解实现跨域;
通过配置文件实现跨域;
通过 CorsFilter 对象实现跨域;
通过 Response 对象实现跨域;
通过实现 ResponseBodyAdvice 实现跨域。
跨域问题的本质是浏览器为了保证用户的一种安全拦截机制,想要解决跨域问题,只需要告诉浏览器“我是自己人,不要拦我”就行展开评论点赞 - #青训营笔记创作活动#
2023/2/2 阅读打卡day7
1.计数器:
程序执行逻辑:
可以在程序中设置一个变量 count,当过来一个请求我就将这个数 +1,同时记录请求时间。
当下一个请求来的时候判断 count 的计数值是否超过设定的频次,以及当前请求的时间和第一次请求时间是否在 1 分钟内。
如果在 1 分钟内并且超过设定的频次则证明请求过多,后面的请求就拒绝掉。
如果该请求与第一个请求的间隔时间大于计数周期,且 count 值还在限流范围内,就重置 count。
这种方法虽然简单,但也有个大问题就是没有很好的处理单位时间的边界。
2.滑动窗口:
滑动窗口把固定时间片进行划分,并且随着时间的流逝,进行移动,固定数量的可以移动的格子,进行计数并判断阀值。
格子的数量影响着滑动窗口算法的精度,依然有时间片的概念,无法根本解决临界点问题。
3.漏桶:
漏桶算法有以下特点:
漏桶具有固定容量,出水速率是固定常量(流出请求)
如果桶是空的,则不需流出水滴
可以以任意速率流入水滴到漏桶(流入请求)
如果流入水滴超出了桶的容量,则流入的水滴溢出(新请求被拒绝)
4.令牌桶:
令牌桶的特点:
令牌按固定的速率被放入令牌桶中
桶中最多存放 B 个令牌,当桶满时,新添加的令牌被丢弃或拒绝
如果桶中的令牌不足 N 个,则不会删除令牌,且请求将被限流(丢弃或阻塞等待)
5.Redis + Lua 分布式限流:
而分布式限流,以集群为维度,可以方便的控制这个集群的请求限制,从而保护下游依赖的各种服务资源。
分布式限流最关键的是要将限流服务做成原子化,我们可以借助 Redis 的计数器,Lua 执行的原子性,进行分布式限流展开评论点赞 - #青训营笔记创作活动#
2023/1/29阅读打卡day6
1.签名:
接口请求方将请求参数 + 时间戳 + 密钥拼接成一个字符串,然后通过md5等hash算法,生成一个前面sign。
然后在请求参数或者请求头中,增加sign参数,传递给API接口。
API接口的网关服务,获取到该sign值,然后用相同的请求参数 + 时间戳 + 密钥拼接成一个字符串,用相同的m5算法生成另外一个sign,对比两个sign值是否相等。
2.加密:
我们可以将所有的数据,安装一定的规律拼接成一个大的字符串,然后在加一个密钥,拼接到一起。
3. ip白名单:
只有在白名单中的ip地址,才能成功请求API接口,否则直接返回无访问权限。
ip白名单也可以加在API网关服务上。
4. 限流:
限流方法有三种:
对请求ip做限流:比如同一个ip,在一分钟内,对API接口总的请求次数,不能超过10000次。
对请求接口做限流:比如同一个ip,在一分钟内,对指定的API接口,请求次数不能超过2000次。
对请求用户做限流:比如同一个AK/SK用户,在一分钟内,对API接口总的请求次数,不能超过10000次。
5. 参数校验:
我们需要对API接口做参数校验,比如:校验必填字段是否为空,校验字段类型,校验字段长度,校验枚举值等等。
6. 统一返回值:
正常返回数据是一种json格式
所有的API接口都必须经过API网关,API网关捕获该业务异常,然后转换成统一的异常结构返回,这样能统一返回值结构。
7. 统一封装异常:
返回码code是500,返回信息message是服务器内部异常。
这样第三方平台就知道是API接口出现了内部问题,但不知道具体原因,他们可以找我们排查问题。
我们可以在内部的日志文件中,把堆栈信息、数据库信息、错误代码行数等信息,打印出来。
我们可以在gateway中对异常进行拦截,做统一封装,然后给第三方平台的是处理后没有敏感信息的错误信息。
8. 请求日志:
我们需要把API接口的请求url、请求参数、请求头、请求方式、响应数据和响应时间等,记录到日志文件中。
最好有traceId,可以通过它串联整个请求的日志,过滤多余的日志。
展开评论点赞 - #青训营笔记创作活动#
2023/1/23 阅读打卡day6
1.使用group_concat(code)可以把分组后相同的拼接在一起
2.char_length(name)可以获取我们需要的字符串的长度,我们可以根据这个来排序
3.locate("苏三",name)关键字越靠左的,越排在前面
4.replace将a内容替换成b内容set name=replace(name,"a","b")
5.now可以获取当前时间,now(3)可以返回毫秒
6.insert into `brand`(`id`,`code`) select null,code from `order` where code in(`004`),这样就可以把另一个表的结果集中插入过来
7.insert into .... ignore 例如:insert ignore into `brand`(`id`,`name`) values(123,`108`)这样就可以判断是否已经存在,如果没有存在该这样的数据,则可以直接插入
8.select ...for update(自带的悲观锁)
例如:begin: select * from `user` where id=1
for update;
//业务逻辑处理
update `user` set score=score-1 where id=1;commit;
这样使用for update 锁住一行记录,其他事务就不能在该事务提交前,去更新那个数据
9.on duplicate key update该语法会在插入数据之前判断,如果主键或者唯一索引不存在,则插入,如果存在,则进行更新操作
例如: insert into ....values ... on duplicate key update name=`chen`,edit_date=now(3);
注意:在高并发可能会死锁
10.show create table `xxx`可以看到表的所有索引
11.create table ... select 可以达到数据备份的作用
12.explain ..........(select等等语句)可以查看mysql的执行计划,显示索引的使用情况
展开评论点赞 - #青训营笔记创作活动#
2023/1/22 阅读打卡day5
1.GET是只读方法,没有修改数据或者损坏数据的风险,GET API是幂等
2.POST通常导致服务器上状态的改变或者创建新资源
3.PUT API一般用来更新先有资源
4.Delete用来删除指定的资源
5.POST.PUT比较不安全,不可缓存展开评论点赞 - #青训营笔记创作活动#
2023/1/21 阅读打卡day4
我明白了去了解一些优秀框架的源码会是一个很好的提升方式。通过看源码,我们能学到业界大佬们优秀的设计理念、编码风格、设计模式的使用、高效数据结构算法的使用、魔鬼细节的巧妙应用等等。这些东西都是助力我们成为一个优秀工程师不可或缺的。展开评论点赞 - #青训营笔记创作活动#
2023/1/18阅读打卡day3
加唯一索引可以保证数据并发写入时数据唯一,而且最省事省心。
数据库通过引入一层buffer pool内存来提升读写速度,普通索引可以利用change buffer提高数据插入的性能。
唯一索引会绕过change buffer,确保把磁盘数据读到内存后再判断数据是否存在,不存在才能插入数据,否则报错,以此来保证数据是唯一的。
展开评论点赞 - #青训营笔记创作活动#
2023/1/16,阅读打卡day2
Mysql 的表数据是以页的形式存放的,页在磁盘中不一定是连续的。
页的空间是 16K, 并不是所有的空间都是用来存放数据的,会有一些固定的信息,如,页头,页尾,页码,校验码等等。
在 B+ 树中,叶子节点和非叶子节点的数据结构是一样的,区别在于,叶子节点存放的是实际的行数据,而非叶子节点存放的是主键和页号。
索引结构不会影响单表最大行数,2kw 也只是推荐值,超过了这个值可能会导致 B + 树层级更高,影响查询性能。展开评论点赞