随着对于Mysql的了解,我们知道Mysql有三种常用的数据引擎,分别是:MYISAM,INNODB,MEMORY。其中由于MYISAM不支持事务,行锁等原因的限制,被MySQL官方也逐渐放弃,这里暂不做讨论。但不知道大家是否有和我最初一样的困惑,既然MYSQL也有可以基于内存操作的数据引擎Memory,为什么还需要和Redis配合使用呢?接下来,我会和大家分享一下其中的原因。
什么是Memory引擎?Memory引擎是Mysql的内存引擎,在实现上,Memory存储引擎不同于Innodb这种组织索引结构(索引即是数据,即数据存放在主键索引上),而是将索引和数据分开存储。索引采用Hash的形式,存放主键id和指向数据的指针,而数据则按插入顺序存放。我们称这种数据组织方式为堆组织方式。
在线上使用Memory引擎存储数据可能会出现那些问题? 1.Memory不支持行锁只支持表锁由于Memory存储引擎的这也特性,导致了Memory存储引擎在进行并发操作时会造成大量的阻塞,效率不高。
2.数据持久化问题Memory存储引擎的所有数据都存储在内存当中,当数据库重启时,无论是否是异常重启还是正常的升级重启,由于其没有持久化机制,会导致内存当中的数据全部丢失。更严重的是,如果如果这个现象发生在从库,主库同步过来的所有update语句都执行失败,造成主备同步的停滞。如果数据库采用双M架构,那么在数据库重启之前,会向binlog中写入一条delete from table t ,这条binlog传到另一个库执行后会造成两个库的内存表数据全部丢失。这是线上业务所不能容忍的。
Redis的特点 1.redis有两种数据持久化方式redis支持两种数据持久化方式:RDB和AOF,这也是redis区别与其他nosql内存数据库的一个主要特点。
RDB主要可以用作冷备,默认情况下每5分钟将会fork出一个子进程,进行当前数据快照的持久化(这里的内存为了保证备份期间数据的一致性,这里还用到了一个概念:写时复制COW)。除此之外,RDB还具备一下几个特点:
生成一组持久化文件,每一个文件都代表了某一时刻的内存数据快照。
数据恢复速度快。
由于是由后台子进程进行数据备份,对线上系统的QPS影响较小。但如果后台需要备份的数据量较大,则由于进程调度原因,可能会导致线上业务停滞。
默认每五分钟生成一次数据副本,数据的可靠性并不高。
AOF则是以追加写的方式,将对Redis的更新操作全部写入aof文件。aof具有以下特点:
AOF默认每1s通过后台线程进行一次fsync操作,数据的可靠性比较高,最多丢失1s的数据。 AOF采用append-only的方式写入日志文件,由于是顺序写,没有磁盘寻址的开销,速度很快。 AOF日志的可读性很强,可以执行一些紧急处理。 但是AOF日志普遍要比RDB文件大,这是由于AOF日志需要记录redis实例启动以来的所有更新操作,以便对数据库进行重放,恢复数据。 由于需要保证数据的可靠性而每秒执行的fsync操作,会降低线上的QPS。因此通过RDB和AOF的配合使用,就可以在保证效率的同时尽可能的保证数据的可靠性。这是Memory存储引擎所不具备的。
除此之外,Redis通过nio模型,利用单个线程监听多个socket,将对redis的操作全部转换为文件事件操作。大大提高了并发性。
综上所述,即使Mysql有内存引擎Memory,在实际的线上生产当中,也无法用其代替Redis。