什么是NoSQL
NoSQL=Not Only SQL 意即“不仅仅是SQL”。
为什么是NoSQL
High performance -对数据库高并发读写的需求
Huge Storage -对海量数据的高效率存储和访问的需求
High Scalability&&High Availability -对数据库的高可扩展性和高可用性的需求
主流NoSQL产品
键值存储数据库
相关产品:Redis
典型应用:内容缓存,主要用于处理大数据的高访问负载。
数据模型:一系列键值对
优势:快速查询
劣势:存储的数据缺少结构化
列存储数据库
相关产品:HBaSE
典型应用:分布式文件系统
数据模型:以列簇式存储,将同一列数据存在一起
优势:查找速度快,可拓展性强,更容易进行分布式拓展
文档型数据库
相关产品:MongoDB
典型应用:web应用
数据模型:数据结构要求不严格
劣势:查询性能不高,而且缺乏统一的查询语法
图形数据库
相关数据库:Neo4J、InfoGrid、Infinite Graph
数据模型:图结构
优势:利用图结构相关算法
劣势:需要对整个图计算才能得出结果,不容易做分布式的集群方案。
NoSQL特点
易拓展
大数据量、高性能
灵活的数据模型
高可用
Redis应用场景
缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
聊天室的在线好友列表
任务队列。(秒杀、抢购、12306等等)
应用排行榜
网站访问统计
数据过期处理(可以精确到毫秒)
分布式集群架构中的session分离
Redis数据结构
Value支持五种数据类型
字符串
哈希
字符串列表
字符串集合
有序字符串集合
定义key:
key不要太长,最好不要超过1024个字节,这不仅会消耗内存还会降低查找效率。
Key不要太短,如果太短会降低key的可读性。
在项目中,key最好有一个统一的命名规范。
存储String
在Redis中字符串类型的Value最多可以容纳的数据长度是512M。
常用命令
Set key value:设定key 持有指定字符串value,如果存在则覆盖。
Get key :获取key的value。
Getset key value :先获取该key的值,然后在设置该key的值
Del key:删除指定key
incrby key increment:将指定的key的value原子性增加increment.
decrby key decrement:将指定的key的value原子性减少decrement.
append key value :拼凑字符串
存储hash
redis中的Hash类型可以看成具有Srting Key和String Value的map容器。每一个Hash可以存储4294967295个键值对。
常用命令
hset key field value:未指定的key设定field/value对(键值对)。
hmset key field value [field2 value2...]:设置key中的多个filed/value
hget key filed:返回指定的key中的filed的值
hmget key fileds:获取key中的多个filed的值
hgettall key:获取key 中的所有filed-value
hdel key fileds:可以删除一个或多个字段
redis持久化
RDB方式
默认情况下,RDB开启,AOF关闭。
这两种形式都可以将存储在内存中的数据库数据以文件形式保存到硬盘中,防止数据丢失。
文件位置:/var/lib/redis/6379
RDB持久化功能可以将服务器包含的所有数据库数据以二进制文件的形式保存到硬盘中,创建RDB类型的文件,默认为
dump.rdb。服务器再次启动时会载入RDB文件,根据RDB文件的内容、还原服务器原有的数据库数据。
创建RDB文件方式
前两种需要用户手动执行,第三种有redis服务器自动执行
服务器执行客户端发送SAVE命令
服务器执行客户端发送BGSAVE命令
使用save配置选项设置的自动保存条件被满足,服务器自动执行BGSAVE
SAVE命令
执行save命令的过程中,即创建RDB文件过程中,redis服务器将被阻塞,无法处理客户端发送的命令请求,只有在SAVE命令执行完毕之后,,服务器才重新开始处理客户端发送的命令请求。
如果RDB文件已经存在,那么服务器将自动使用新的RDB文件去代替旧的RDB文件。(为防止rdb文件丢失或被恶意篡改,可以设置定时将rdb文件转移到别的位置,文件命名标明保存时间)
BGSAVE命令
执行bgsave命令同样会创建一个新的RDB文件,但这个命令执行过程中不会造成redis服务器阻塞。
【1、当redis服务器接受到BGSAVE命令时,他不会自动创建RDB文件,而是通过fork()来生成一个子进程,然后由子进程负责创建RDB文件,而自己继续处理客户端的命令请求 2、当子进程创建好RDB文件并退出时,他会向父进程(即负责处理命令请求的redis服务器)发送一个信号,告知他RDB文件已经创建完毕 3、最后redis服务器(父进程)解手子进程创建的RDB文件,BGSAVE执行完毕】
创建子进程会消耗额外的内存,所以SAVE创建RDB文件的速度会比BGSAVE块,可以集中资源来创建RDB文件。SAVE和BGSAVE没有孰好孰坏之分,如果数据库正在上线当中,用BGSAVE更好;而如果维护停机期间,则使用SAVE,因为此时系统阻塞也没关系,创建速度会更快,任务可以更快得完成。
自动创建RDB文件
默认redis.conf文件中为如下设置,可自行修改。只要三个条件满足任意一个,服务器就会执行BGSAVE。RDB文件创建后,服务器会将时间计数器和次数计数器清零,重新开始记录
save 900 1 :如果距离上次创建RDB文件已经过去了900秒,且服务器所有数据库总共已经发生了不少于1次修改,那么执行BGSAVE命令
save 300 10 :如果距离上次创建RDB文件已经过去了300秒,且服务器所有数据库总共已经发生了不少于10次修改,那么执行BGSAVE命令
save 60 10000:如果距离上次创建RDB文件已经过去了60秒,且服务器所有数据库总共已经发生了不少于10000次修改,那么执行BGSAVE命令
RDB持久化的缺点
创建RDB文件需要将服务器所有的数据库的数据保存起来,这是一个非常耗费资源和时间的操作,所以服务器需要隔一段时间才创建一个新的RDB文件,也就是说,创建RDB文件的操作不能执行得过于频繁,否则就会严重得影响服务器性能。
相比而言,AOF持久化的巨大优势就是用户可以根据自己的需要对AOF持久化进行调整,让redis在遭遇意外停机时不丢失任何数据,或者只丢失一秒钟的数据。
AOF方式
AOF持久化保存数据库的方法是:每当有修改的数据库的命令被执行时,服务器就会将执行的命令写入到AOF文件(日志文本文件)的末尾。
因为AOF文件里存储了服务器执行过得所有数据库修改的命令,所以给定一个AOF文件,服务器只要重新执行一遍AOF文件里面包含的所有命令,就可以达到还原数据库的目的。
安全性问题
虽然服务器执行一个修改数据库的命令,就会被执行的命令写入到AOF文件,但这并不意味着AOF文件持久化不会丢失任何数据。
在目前常见的操作系统中,执行系统调用write函数,将一些内容写入到某个文件里面时,为了提高效率,系统通常不会直接将内容写入到硬盘里面,而是先将内容放在一个内存缓冲区(buffer)里面,等到缓冲区被填满,或者用户执行fsync调用和fdatasync调用时才将储存在缓冲区里面的内容真正的写入到硬盘里。
对于AOF持久化而言,当一条命令真正的被写入到硬盘里面时,这条命令才不会因为停机而意外丢失。
因此,AOF持久化在遭遇停机时丢失命令的数量,取决于命令被写入到硬盘的时间。
为了控制redis服务器在遇到意外停机时丢失的数据量,redis为AOF持久化提供了appendfsync选项,这个选项的值可以是always、everysec或者no。
Always
服务器每写入一个命令,就会调用一次fdatasync,将缓冲区里面的命令写入到硬盘里。在这种模式下,服务器即使遇到意外停机,也不会丢失任何自己已经成功执行得命令数据
Everysec
服务器每一秒重调一次fdatasync,将缓冲区里面的命令写入到硬盘里面。在这种模式下,服务器即使遭遇意外停机,最多只丢失一秒钟内执行得命令数据
No
服务器不主动调用fdatasync,由操作系统决定何时将缓冲区里面的命令写入到硬盘里面。在这种模式下,服务器遭遇意外停机时,丢失的数据是不确定的
运行速度:alawys的速度慢,everysec和no都很快。默认值为:everysec
AOF文件中的冗余命令
随着服务器的不断运行,为了记录数据库发生的变化,服务器会将越来越多的命令写入到AOF文件里面,使得AOF文件的体积不断增大。 为了让AOF文件的大小控制在合理的范围,避免他胡乱增长,redis提供了AOF重写功能,通过这个功能,服务器可以产生一个新的AOF文件:
新的AOF文件记录的数据库数据和原有AOF文件记录的数据库数据完全一样
新的AOF文件会使用可能少的命令来记录数据库数据,因此新的AOF文件的体积通常会比原有的AOF文件体积小很多
AOF重写期间,服务器不会阻塞,可以正常处理客户端发送的命令请求
两种触发AOF重写的方法
客户端向服务器发送 BGREWRITEAOF 命令
通过设置配置选项来让服务器自动执行BGREWRITEAOF命令,他们分别是:①auto-aof-rewrite-min-size ,触发AOF重写所需的最小体积,只要在AOF文件的体积大于或等于size时,服务器才会考虑是否需要AOF重写,这个选项用于避免对体积过小的AOF文件进行重写。②auto-aof-rewrite-percentage ,指定触发重写所需的AOF文件体积百分比,当AOF文件体积大于auto-aof-rewrite-min-size指定的体积,并且超过上一次重写之后的AOF文件体积的percent%时,就会触发AOF重写。(将这个值设置为0表示关闭自动AOF重写)。
AOF的特点
AOF文件会产生越来越多的冗余命令,使得文件体积不断增大,而执行AOF重写操作后,服务器可以创建一个保存相同数据库数据,但不包含任何冗余命令的新的AOF文件,并使用这个新的AOF文件来替代原有的AOF文件。
redis应用场景
(1)、缓存
缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力。Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非常多。
(2)、排行榜
很多网站都有排行榜应用的,如京东的月度销量榜单、商品按时间的上新排行榜等。Redis提供的有序集合数据类构能实现各种复杂的排行榜应用。
(3)、计数器
什么是计数器,如电商网站商品的浏览量、视频网站视频的播放数等。为了保证数据实时效,每次浏览都得给+1,并发量高时如果每次都请求数据库操作无疑是种挑战和压力。Redis提供的incr命令来实现计数器功能,内存操作,性能非常好,非常适用于这些计数场景。
(4)、分布式会话
集群模式下,在应用不多的情况下一般使用容器自带的session复制功能就能满足,当应用增多相对复杂的系统中,一般都会搭建以Redis等内存数据库为中心的session服务,session不再由容器管理,而是由session服务及内存数据库管理。
(5)、分布式锁
在很多互联网公司中都使用了分布式技术,分布式技术带来的技术挑战是对同一个资源的并发访问,如全局ID、减库存、秒杀等场景,并发量不大的场景可以使用数据库的悲观锁、乐观锁来实现,但在并发量高的场合中,利用数据库锁来控制资源的并发访问是不太理想的,大大影响了数据库的性能。可以利用Redis的setnx功能来编写分布式的锁,如果设置返回1说明获取锁成功,否则获取锁失败,实际应用中要考虑的细节要更多。
(6)、 社交网络
点赞、踩、关注/被关注、共同好友等是社交网站的基本功能,社交网站的访问量通常来说比较大,而且传统的关系数据库类型不适合存储这种类型的数据,Redis提供的哈希、集合等数据结构能很方便的的实现这些功能。
(7)、最新列表
Redis列表结构,LPUSH可以在列表头部插入一个内容ID作为关键字,LTRIM可用来限制列表的数量,这样列表永远为N个ID,无需查询最新的列表,直接根据ID去到对应的内容页即可。
(8)、消息系统
消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。