Agenda:
缓存策略的概念和实例
缓存策略的难点:不同特点的缓存数据的清理机制
分布策略的概念和实例
分布策略的难点:共享数据安全性与代码复杂度的平衡
缓存
缓存策略
性能问题表现:
并发数不足,也就是同时请求的客户过多,服务器的内存耗尽
处理延迟过长,CPU占用满100%
抽象资源:
时间资源:CPU和磁盘读写
空间资源:内存和网卡带宽
缓存策略,其实是用内存的空间,换取磁盘的读写空间
网络游戏的服务端程序,所有的写操作都先去写内存中的结构,然后定期再由服务器主动写回到数据库中,这样可以把多次的写数据库操作变成一次写操作,也能节省很多写数据库的消耗。这种做法也是用空间换时间的策略。
缓存的本质,除了让“已经处理过的数据,不需要重复处理”以外,还有“以快速的数据存储读写,代替较慢速的存储读写”的策略
对缓存数据的编程处理,采用序列化的方式,也可以采用深拷贝的方式,
一般来说,缓存的数据越解决使用时的内存结构,其转换速度就越快,在这点上,Protocol Buffer采用TLV编码,就比不上直接memcpy的一个C结构体,但是比编码成纯文本的XML或者JSON要来的更快。因为编解码的过程往往要进行复杂的查表映射,列表结构等操作
缓存难点-缓存清理
使用命令清理相关内存
使用字段逻辑判断,根据一些特征数据,判断是否有不一致的地方,
静态的缓存
以及运行时变化的缓存数据,
按照重要级来分割
按照使用部分分割
分布
分布策略
划分多个进程的架构,一般会有两种策略:一种是按功能来划分,比如负责网络处理的一个进程,负责数据库处理的一个进程,负责计算某个业务逻辑的一个进程。另外一种策略是每个进程都是同样的功能,只是分担不同的运算任务而已
在调用多进程服务的策略上,我们也会有一定的策略选择,其中最著名的策略有三个:一个是动态负载均衡策略;一个是读写分离策略;一个是一致性哈希策略。
多进程技术
多线程技术,内存使用不可控,对于同一数据的使用,需要考虑复杂的”锁”问题
select/epoll, 非阻塞操作,
多线程和异步的例子,最著名就是Web服务器领域的Apache和Nginx的模型。Apache是多进程/多线程模型的,它会在启动的时候启动一批进程,作为进程池,当用户请求到来的时候,从进程池中分配处理进程给具体的用户请求,这样可以节省多进程/线程的创建和销毁开销,但是如果同时有大量的请求过来,还是需要消耗比较高的进程/线程切换。而Nginx则是采用epoll技术,这种非阻塞的做法,可以让一个进程同时处理大量的并发请求,而无需反复切换。对于大量的用户访问场景下,apache会存在大量的进程,而nginx则可以仅用有限的进程(比如按CPU核心数来启动),这样就会比apache节省了不少“进程切换”的消耗,所以其并发性能会更好。
分布式编程复杂度
多线程部分
基于回调
基于协程
lamda表达式,闭包,promise手段
动态多进程fork——同质的并行任务
多线程——能明确划的逻辑复杂的并行任务
异步并发回调——对性能要求高,但中间会被阻塞的处理较少的并行任务
协程——以同步的写法编写并发的任务,但是不合适发起复杂的动态并行操作。
函数式编程——以数据流为模型的并行处理任务
函数式编程的语言,比如LISP或者Erlang,其核心数据结果是链表——一种可以表示任何数据结构的结构。我们可以把所有的状态,都放到链表这个数据列车中,然后让一个个函数去处理这串数据,这样同样也可以传递程序的状态。这是一种用栈来代替堆的编程思路,在多线程并发的环境下,非常的有价值。
分布式数据通信
消息队列
分布式缓存策略
利用哈希表来解决缓存的数据同步
我们的“表”要有能把数据在A、B两个进程间同步的能力。因此我们一般会用三种策略:租约清理、租约转发、修改广播
租约清理
租约转发
这样无需清理,
- 修改广播
dns的缓存策略