一.什么是 CGI?什么是 FastCGI?PHP-fpm,FastCGI,Nginx 之间是什么关系?
CGI,通用网关接口,用于WEB服务器和应用程序间的交互,定义输入输出规范,用户的请求通过WEB服务器转发给FastCGI进程,FastCGI进程再调用应用程序进行处理,如PHP解析器,应用程序的处理结果如html返回给FastCGI,FastCGI返回给Nginx 进行输出。假设这里WEB服务器是Nginx,应用程序是 PHP,而 PHP-fpm 是管理 FastCGI 的,这也就是 PHP-fpm,FastCGI,和 Nginx 之间的关系。
FastCGI 用来提高 cgi 程序性能,启动一个master,再启动多个 worker,不需要每次解析 PHP.ini. 而 PHP-fpm 实现了 FastCGI 协议,是 FastCGI 的进程管理器,支持平滑重启,可以启动的时候预先生成多个进程。
二.memcache 和 Redis 的区别
数据结构:memcache仅支持简单的key-value形式,Redis支持的数据更多(string字符串,set集合,list列表,hash散列,zset有序集合);
分布式:Redis做主从结构,memcache服务器需要通过hash一致化来支撑主从结构
实际运用中可以redis,memcache结合,memcache可作为session存储的方式,session都是KV类型键值对。
1. Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcache相比一个最大的区别。
2. Redis在很多方面具备数据库的特征,或者说就是一个数据库系统,而Memcache只是简单的K/V缓存。
3. 他们的扩展都需要做集群;实现方式:master-slave、Hash。
4. 在100k以上的数据中,Memcache性能要高于Redis。
5. 如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcache。当然,这和你的应用场景和数据特性有关。
6. 如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcache都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。
7. Redis和Memcache在写入性能上面差别不大,读取性能上面尤其是批量读取性能上面Memcache更强
8.Redis 提供了多种不同级别的持久化方式:
RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
三.什么是 Redis 穿透和雪崩
**缓存穿透**:就是访问redis中一个不存在的key的时候,会直接穿过缓存,去数据库中进行查询.
如果是黑客,进行恶意攻击的时候,每次都请求超过2000个/秒的时候,这个时候MysqL基本上就挂了.
解决办法是:每次从数据库中查询到一个不存在的key的时候,就写一个空值到缓存库中,有恶意攻击的时候,直接从缓存中取到这个空值.
**缓存雪崩**:就是每秒有5000个请求过来时候,redis缓存库崩了,然后这些请求瞬间落在了MysqL数据库上,直接导致数据库死机.
解决方案就是:
事前:提高缓存库的高可用,使用主从结构加哨兵 cluster集群,
事中:使用ehcache+hystrix限流组件(当请求量非常巨大的时候,就调用自己开发好的一个降级饿组件,返回一些默认值,如友情提示,或者空白值)
事后:做持久化,尽快恢复缓存集群,一旦恢复,自动从磁盘上读取数据,恢复内存中的数据.
四.redis 消息队列先进先出需要注意什么?
通常使用一个list来实现队列操作,这样有一个小限制,所以的任务统一都是先进先出,如果想优先处理某个任务就不太好处理了,这就需要让队列有优先级的概念,我们就可以优先处理高级别的任务,实现方式有以下几种方式:
1)单一列表实现:队列正常的操作是 左进右出(lpush,rpop)为了先处理高优先级任务,在遇到高级别任务时,可以直接插队,直接放入队列头部(rpush),这样,从队列头部(右侧)获取任务时,取到的就是高优先级的任务(rpop)
2)使用两个队列,一个普通队列,一个高级队列,针对任务的级别放入不同的队列,获取任务时也很简单,redis的BRPOP命令可以按顺序从多个队列中取值,BRPOP会按照给出的 key 顺序查看,并在找到的第一个非空 list 的尾部弹出一个元素,redis> BRPOP list1 list2 0
`list1 做为高优先级任务队列`
`list2 做为普通任务队列`
`这样就实现了先处理高优先级任务,当没有高优先级任务时,就去获取普通任务`
`方式1最简单,但实际应用比较局限,方式3可以实现复杂优先级,但实现比较复杂,不利于维护`
`方式2是推荐用法,实际应用最为合适`
五.Redis 如何防止高并发?
其实redis是不会存在并发问题的,因为他是单进程的,再多的命令都是一个接一个地执行的。我们使用的时候,可能会出现并发问题,比如获得和设定这一对。Redis的为什么 有高并发问题?Redis的的出身决定
Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题。发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。
同时,单线程的天性决定,高并发对同一个键的操作会排队处理,如果并发量很大,可能造成后来的请求超时。
在远程访问redis的时候,因为网络等原因造成高并发访问延迟返回的问题。
解决办法
在客户端将连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。
服务器角度,利用setnx变向实现锁机制。
六.说说对 sql 语句优化有哪些方法?
(1)Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。
(2)用EXISTS替代IN、用NOT EXISTS替代NOT IN。
(3) 避免在索引列上使用计算
(4)避免在索引列上使用IS NULL和IS NOT NULL
(5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
(6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
(7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
原文链接:https://www.f2er.com/phpinterview/880760.html