一、背景
在互联网项目中往往存在大数据量的需求,比如一些商品抢购的场景,或是访问量瞬间较大的时候,一瞬间成千上万的请求就会到来,比如在双十一活动。
当数据量的总大小一个机器放不下时;数据索引一个机器的内存放不下时;访问量(读写混合)一个实例放不下时。
(1)单机模式:
app——>dao——>mysql,如果每次存储成千上万条数据,这样很会导致mysql的性能很差,存储以及读取速度很慢;
然后就演变成,app——>dao——>缓存——>mysql,缓存+mysql+垂直拆分的方式。将所有的数据先保存到缓存中,然后再存入mysql中,减小数据库压力,提高效率。
但是当数据再次增加到又一个量级,由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力,读写集中在一个数据库上让数据库不堪重负。
(2)主从分离模式:
使用主从复制技术来达到读写分离,以提高读写性能和读库的可扩展性。Mysql的master-slave模式成为这个时候的网站标配。
MySQL的主从复制,读写分离的基础之上,这时MySQL主库的写压力开始出现瓶颈,而数据量的持续猛增。
由于MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替MyISAM。
(3)分库分表模式
将变化小的、业务相关的放在一个数据库,变化多的,不相关的数据放在一个数据库。
二、NoSQL的优势
易扩展 :不需要固定的模式,无需多余的操作就可以进行横向的扩展。相对于关系型数据库可以减少表和字段特别多的情况。也无型之间在架构的层面上带来了可扩展的能力 。
大数据量提高性能:关系型数据库在面对高并发时读写性能非常差(磁盘读,相当慢),面对海量数据的时候效率非常低。
而Nosql存储的格式都是key-value类型的,并且存储在内存中,非常容易存储,而且对于数据的 一致性是 弱要求。Nosql无需sql的解析,提高了读写性能。
内存操作的级别是毫秒级的比硬盘操作秒级操作自然高效不少,较少了磁头寻道、数据读取、页面交换这些高开销的操作。
多样灵活的数据模型 :可以存储String,hash,set、Zset等数据类型,还可以保存javaBean以及多种复杂的数据类型。
三、redis简介
redis是Nosql数据库中使用较为广泛的非关系型内存数据库,redis内部是一个key-value存储系统。
它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型,类似于Java中的map)。
redis基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器。
四、redis的使用场景
1、缓存数据(需要从3个方面考虑)
业务数据常用吗?命中率如何?如果命中率很低,那就没必要用redis把这一数据写入缓存了。
该业务数据是读操作多?还是写操作多?如果写操作多,那就需要频繁的将数据写到数据库中,redis不是做这个的,所以就没必要将这部分数据写入redis的缓存中了。
业务数据的大小如何?如果要存储几百兆字节的文件,这会给缓存带来巨大的压力,因为会耗费我们的内存,影响速度,有没有必要?
2、高并发(高速读写)
异步地去写入数据库,而在高速读或者写的情况下使用redis去应对,把这些需要高速读或写的数据缓存到redis中。而在满足一定的条件后,再将这些数据写入到内存中。
也就是,当一个请求到达服务器,只是把业务数据放在redis上进行读写,而没有进行任何对数据库的操作,换句话说就是,系统仅仅是操作redis缓存,而没有操作数据库。
这个速度就比操作数据库要快的多。但是缓存不能持久化,因此需要把这些数据存入数据库,所以在一个请求操作完redis的读或写操作后,会判断该高速读写业务是否结束。
这个条件一般是商品剩余个数为0,抢红包剩余金额为0。如果不成立,就不会操作数据库,否则会触发事件将redis缓存的数据以批量的形式一次性写入数据库,从而完成持久化操作。
而实际上,真正的情况远比上述更为复杂,因为实际中要考虑高并发下的数据安全和一致性的问题,以及有效请求无效请求以及事务一致性等诸多问题。