0%

缓存的设计

数据库的性能相比而言比较差,当用户量上来以后就不能直接读数据库,否则会导致连接数超过数据库连接串数,出现大量的慢请求,而且大量的数据其实并不会频繁的更新数据,这个时候就可以使用缓存来优化速度.比如使用redis,redis的读写速度要快于MongoDB,使用redis不仅可以减少MongoDB压力,也可以加快接口响应速度.
用户先请求redis,如果有数据就直接返回,不再查询数据库,如果redis中没有再查询数据库

缓存的读写策略

redis和MongoDB中都有一份数据,那如果两端的数据不一致怎么办呢?

Cache Aside 策略

如果先更新数据库后更新缓存,会出现什么问题呢?
在2个并发写请求时可能就会出现问题

阅读全文 »

背景

分享短链记录表需要定期做清除,由于数据量较大,而且对数据库操作的次数很多,原来使用定时任务的方式来删除,会对数据库造成短时内的性能波动

所以打算使用其他方式来处理这个问题

TTL索引

TTL全称是(Time To Live),TTL索引能对一个单列配置过期属性来实现对文档的自动过期删除,我们可以在对字段创建索引时添加expireAfterSeconds选项将索引转换为TTL索引,该字段需要是date类型

在以下几种场景下即使索引设置了expireAfterSeconds属性也不会生效

  • 如果该字段不是date类型,则文档不会过期
  • 如果文档没包含索引的这个字段,则文档不会过期
阅读全文 »

背景

现有索引

1
2
{ distributorNo: 1, username: 1 }
{ newAppleUserId: 1, distributorNo: 1 }

现在有个查询

1
2
3
4
5
6
7
8
db.user.findOne({
distributorNo,
$or: [{
username: appleUserId
}, {
newAppleUserId: appleUserId
}]
})

请问这个查询会走哪个索引?

阅读全文 »

苹果App主体迁移

苹果App主体迁移-苹果登录

迁移流程图

![](https://hwl-1255548986.cos.ap-guangzhou.myqcloud.com/hwl.me苹果主体迁移 流程图 .png)

迁移前操作

获取苹果转移标识符 transfer_sub 苹果官方文档

客户端提供参数:

  1. client_id
  2. team_id
  3. key_id
  4. 苹果p8文件
  5. recipient_team_id

后端操作步骤

  1. 获取client_secret,有效期可配置
  2. 获取accessToken,缓存一小时
  3. 获取转移标识符transfer_sub,并入库
阅读全文 »

阿里源

替换brew.git

1
2
3
cd "$(brew --repo)"

git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git

替换homebrew-core.git

1
2
3
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"

git remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git

刷新源

brew update

#清华源

替换brew.git

1
2
3
cd "$(brew --repo)"

git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git

替换homebrew-core.git

1
2
3
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"

git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git

刷新源

brew update

Docker下安装rabbitmq

  1. 拉取镜像
1
docker pull rabbitmq:3-management
  1. 启动镜像(默认用户名密码),默认guest 用户,密码也是 guest
1
docker run -d --hostname rabbitmq --name rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:3-management
  1. 启动镜像(设置用户名密码)
1
docker run -d --hostname rabbitmq --name rabbitmq -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 rabbitmq:3-management
  1. 完成后访问:http://localhost:15672/

介绍

multi是标记一个事务块的开始。事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。

1
2
3
4
const multi = this.app.redis.multi();
multi.zadd(onlineUserListKey, 0, userId);
multi.expire(onlineUserListKey, this.defaultExpire);
await multi.exec();

把多个redis操作放到一个队列里,multi是在服务端缓冲,全部请求到redis以后,等待exec()命令,再一起执行,具有原子性.

pipeline是客户端将执行的命令写入到缓冲中,最后由exec命令一次性发送给redis执行返回

pipeline是通过管道一个个的去执行命令,在redis的客户端做缓冲,减少了redis的连接与请求量,减轻了redis的压力,但是结果依然是按顺序一个个执行,并不具有原子性

1
2
3
4
5
6
const pipeline = this.app.redis.pipeline();
for (let id of ids) {
const key = redisKeys.string.ad(id);
pipeline.get(key);
}
const arr = await pipeline.exec();

总结

multi和pipeline都是将redis命令缓冲,再统一执行,但是则重点不同

  • multi是为了多个操作的原子性,pipeline是为了减少redis的连接和请求压力.
  • multi是服务端缓冲,pipeline是客户端缓冲
  • 请求次数的不一致,multi需要每个命令都发送一次给服务端,pipeline最后一次性发送给服务端,请求次数相对于multi减少
  • multi/exec可以保证原子性,而pipeline不保证原子性

所以当redis操作要求保证原子性时,使用multi/exec,其他时候应该使用pipeline去减轻redis的压力

前言:BST、AVL、RBT、B-tree都是动态结构,查找时间基本都在O(longN)数量级上,BST最差的情况会到O(N)。下面做出详细对比。

二叉查找树 (Binary Search Tree)

二叉查找树又称二叉搜索树,二叉排序树,特点如下:

  1. 左子树上所有结点值均小于根结点
  2. 右子树上所有结点值均大于根结点
  3. 结点的左右子树本身又是一颗二叉查找树
  4. 二叉查找树中序遍历得到结果是递增排序的结点序列。

BST 的操作代价分析:

(1) 查找代价:

任何一个数据的查找过程都需要从根结点出发,沿某一个路径朝叶子结点前进。因此查找中数据比较次数与树的形态密切相关。
当树中每个结点左右子树高度大致相同时,树高为logN。则平均查找长度与logN成正比,查找的平均时间复杂度在O(logN)数量级上。
当先后插入的关键字有序时,BST退化成单支树结构。此时树高n。平均查找长度为(n+1)/2,查找的平均时间复杂度在O(N)数量级上。

(2) 插入代价:

新结点插入到树的叶子上,完全不需要改变树中原有结点的组织结构。插入一个结点的代价与查找一个不存在的数据的代价完全相同。

阅读全文 »

遍历的种类

二叉树遍历主要分为:

  • 深度优先遍历: 先访问子节点,再访问父节点,最后是第二个子节点
  • 广度优先遍历: 先访问第一个子节点,再访问第二个子节点,最后访问父节点

其中深度优先遍历又可以根据遍历的顺序分为:

  • 前序遍历(Pre-Order Traversal)
  • 中序遍历(In-Order Traversal)
  • 后序遍历(Post-Order Traversal)
阅读全文 »

面对互联网的技术日新月异,所要掌握的东西也越来越多。

1.关于网络领域的知识(掌握和了解)

a) 协议:tcp、udp、multicast
b) IO (BIO、NIO、AIO)
c) Socket
d) NIO(Netty/Mima)
e) 序列化和反序列化

2.一个http请求,在整个网络中的请求过程

TCP 总共有四层模型:传输层、网络层、数据链路层、物理层

阅读全文 »