问题一:Redis的事务特性与数据库的事务ACID的比较?

持久性:如果redis中没有开启持久化,那么就是纯内存运行的,一旦重启,所有数据都会丢失,此时可以认为redis不具备事务的持久性;而如果redis开启了持久化,那么可以认为redis在特定条件下是具备持久性的;

隔离性:redis的设计机制是单线程执行命令的。不存在脏读、幻读等操作所以并不需要额外的机制去保障隔离性,先天已经具备串行化的隔离级别了;

原子性:由于redis的单线程特性,能够保证一批命令的执行不会被其他线程中断,但是它并不保证可回滚。即使有部分命令执行失败,其余命令依然会继续执行(如果有语法错误,则全部命令不执行)。

关于redis命令执行中的错误,常见的是语法错误,比如命令的单词输错了。还有的错误比如类型错误,比如对一个String=“abc”进行incr的逻辑,incr也是String支持的命令,但是前提是这个String是一个数值,对于非数值的String执行肯定是不能执行的,但是语法上没有错误。

问题二:常见的对redis做的监控有哪些?

常见的几个监控:

  1. 内存使用率(内存不足可能导致一些非淘汰策略的实例无法写入);
  2. QPS倾斜、内存倾斜。这种是可能存在热点key、大key;这种倾斜问题一般在多个分片redis的时候会出现,其中一个分片的QPS/内存占有量是其他分片的2倍,这种情况就属于不正常的情况;
  3. 连接数:连接数是有限的,当连接数到达阈值时,将会拒绝连接;redis支持的连接数和机器有关,不仅仅是内存,所有机器的配置都会有影响。
  4. 慢查询:使用redis很大的原因是高性能的场景,又由于redis单线程执行命令的特点,某些key出现慢查询之后,可能连锁反应导致其他key响应变慢;
  5. 命中率。

问题三:关于MySQL支持的并发量,网上有说几百的,也有说上万的,不知道平时的经验值是多少?

没有标准答案,比如如果内存巨大,可能大部分查询都在内存中就完成了,那并发量就比读硬盘高很多。。除了硬件也跟数据量有关系,大部分情况下执行的都是耗时长的SQL,那么并发度肯定没有执行耗时低的SQL多。平时一般单实例不超过3000qps。

问题四:为什么redis主从复制不直接使用AOF日志?

  1. AOF占用的空间比RDB大,IO效率比RDB低;
  2. 从库使用RDB恢复的效率比AOF高。

问题五:正常情况下MySQL单表最大支持多少数据量呢?在多大的时候会有性能问题呢?

单表3000万左右的时候需要关注一下,但并不一定说就是需要分表了。规范的情况下,可以提前做一下容量规划,看自己业务逻辑中的SQL,在一定的QPS下的响应时间如何。

表中加索引的话,最好在建表的时候就加好索引,而不是等到数据量很大的时候再去加索引。一般情况下单表的索引不要超过5个,如果超过5个的话,就建议需要评估一下,是不是应该垂直拆分成多个表了。因为建这么多索引,很有可能是这个表的职责过多了,比如用户表就是一个典型的例子,经常用着用着就会变成非常多的索引,有时候为了贪图方便,就一直往一张表里加索引,所以我们需要注意下数据库的表结构设计。

问题六:如果一个索引需要修改,而这个表的数据量很大,一晚上可能来不及,这种情况应该如何操作?

一般这种情况下是为了数据库表结构或者索引的修改不要影响白天正常的服务正确运行。我们可以创建一张新表,然后在新表上建索引,然后再把旧表数据复制过来,然后两个表重命名一下,新表就替换了旧表。

问题七:MySQL的insert buffer thread是做什么用的呢?

insert buffer thread ,顾名思义,就是管理insert buffer的。关于insert buffer,在MySQL中一般主键是自增的,这样在磁盘写入的时候,可以尽量保证是顺序写入。但是对于二级索引来说,其实是无法保障顺序的,为了提高性能,减少磁盘随机写的次数,就把二级索引的写入先缓存在insert buffer里面,按照一定的频率进行合并操作,把多个插入合并到一个操作中,提高插入性能。这种思想很多地方都有体现,比如某些计数的操作,我们等记到一定的的值或者一定间隔的时间,再合并或者批量写入到数据库,这样可以减少写库的次数。

insert buffer thread的作用,是按照一定的频率进行合并操作,把多个插入合并到一个操作中,提高插入性能。

问题八:线程池中有的线程比较耗时,影响了其他线程的正常使用,降低了系统的运行效率,这种情况应该如何处理?

我们可以将那些比较耗时的线程单独建一个线程池,响应比较快的线程放在另外的线程池中,这样子耗时的那些线程就不影响其他的线程了。这里运用的是隔离的思想。