PHP

执行流程

image.png

apcode缓存

HTTP

TCP三次握手

image.png
image.png
image.png

HTTP协议

redis

常用数据结构

string,Hash,List,Set,ZSet+

持久化方案

RDB:快照形式,定期把内存中当前时刻的数据保存到磁盘。Redis默认支持的持久化方案。速度快但是服务器断电的时候会丢失部分数据
AOF:append only file。把所有对redis数据库操作的命令,增删改操作的命令。保存到文件中。数据库恢复时把所有的命令执行一遍即可。两种持久化方案同时开启使用AOF文件来恢复数据库.能保证数据的完整性,但是速度慢。

主从复制

当我们在redis中开启了持久化(RDB或者AOF)但是这样也不能保证数据一定不会丢失,当Redis服务因为硬盘损坏那么数据也就丢失了,这时我们通过主从模式,一个master设置多个slave,那么在slave上面就会有多个备份数据,提高了我们数据的抗灾能力。

主从同步过程

第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

集群原理

Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。

缓存穿透

是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决办法

  1. 对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃。还有最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
  2. 也可以采用一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

    缓存雪崩

    如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。
    解决办法

  3. 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

  4. 可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存
  5. 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀. 比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件
  6. 做二级缓存,或者双缓存策略。A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。

    缓存预热

    就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
    缓存预热解决方案

  7. 直接写个缓存刷新页面,上线时手工操作下;

  8. 数据量不大,可以在项目启动的时候自动进行加载;
  9. 定时刷新缓存;

    缓存更新

    我们知道通过expire来设置key 的过期时间,那么对过期的数据怎么处理呢?除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:

  10. 定时去清理过期的缓存;

  11. 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。

    swoole

    出现的作用

    swoole做为一种网络通信框架,解决php缺失的功能:比如多线程、异步通信、持久连接等

    本质

  • 披着PHP外衣的c语言实现的高级特性,比如多线程、异步通信、持久连接,
  • 面向生产环境的 PHP 异步网络通信引擎

    注意事项

  • swoole是多线程编程,global是不能在多个进程间共享的。

  • 客户端发送的多次请求,服务端是可以一次性接收的。并不是客户端发送一次,服务端接收一次

    mysql

    binlog格式

  • statement模式下,每一条会修改数据的sql都会记录在binlog中。不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。由于sql的执行是有上下文的,因此在保存的时候需要保存相关的信息,同时还有一些使用了函数之类的语句无法被记录复制。

  • row级别下,不记录sql语句上下文相关信息,仅保存哪条记录被修改。记录单元为每一行的改动,基本是可以全部记下来但是由于很多操作,会导致大量行的改动(比如alter table),因此这种模式的文件保存的信息太多,日志量太大。
  • mixed,一种折中的方案,普通操作使用statement记录,当无法使用statement的时候使用row。

    连接池的原理

    索引类型

    normal:表示普通索引
    unique:表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique
    full textl: 表示 全文搜索的索引。 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以

    建立索引原则

    1.选择唯一性索引
    2.为经常需要排序、分组和联合操作的字段建立索引
    3.为常作为查询条件的字段建立索引
    4.限制索引的数目
    5.尽量使用数据量少的索引
    6.尽量使用前缀来索引
    7.删除不再使用或者很少使用的索引

    事务四大特性

    原子性

    指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做

    一致性

    指事务执行前后,数据处于一种合法的状态

    隔离性

    指多个事务并发执行的时候,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰

    持久性

    指事务一旦提交,它对数据库的改变就应该是永久性的

    数据库隔离级别

    读未提交

    最低级别,任何情况都无法保证

    读已提交

    可避免脏读的发生

    可重复读

    可避免脏读、不可重复读的发生

    串行化

    可避免脏读、不可重复读、幻读的发生

  • 脏读,指在一个事务处理过程里读取了另一个未提交的事务中的数据

  • 不可重复读,指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了
  • 幻读,是事务非独立执行时发生的一种现象

    默认的隔离级别为Repeatable read (可重复读)

RPC原理

负载均衡

nginx

高并发

原因

解决方案

设计模式