Redis知识概括

NOSQL简述

nosql是什么?

  • NoSQL(NoSQL = Not Only SQL ),即“不仅仅是SQL”,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题,包括超大规模数据的存储。
  • 例如谷歌或Facebook每天为他们的用户收集万亿比特的数据。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

nosql能干嘛?

  • 易扩展:NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。
  • 大数据量高性能:NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。
    这得益于它的无关系性,数据库的结构简单。一般MySQL使用Query Cache,每次表的更新Cache就失效,是一种大粒度的Cache,在针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了
  • 多样灵活的数据模型:NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦

为什么需要用nosql?

  • 在90年代,一个网站的访问量一般都不大,用单个数据库完全可以轻松应付。 在那个时候更多的都是静态网页,动态交互类型的网站不多。
    ①上述架构下,我们来看看数据存储的瓶颈是什么?
    <1>数据量的总大小 一个机器放不下时
    <2>数据的索引(B+ Tree)一个机器的内存放不下时
    <3>访问量(读写混合)一个实例不能承受
    在这里插入图片描述

  • 后来随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,web程序不再仅仅专注在功能上,同时也在追求性能。程序员们开始大量的使用缓存技术来缓解数据库的压力,优化数据库的结构和索引。开始比较流行的是通过文件缓存来缓解数据库压力,但是当访问量继续增大的时候,多台web机器通过文件缓存不能共享,大量的小文件缓存也带了了比较高的IO压力。在这个时候,Memcached就自然的成为一个非常时尚的技术产品:Memcached(缓存)+MySQL+垂直拆分。
    ①Memcached作为一个独立的分布式的缓存服务器,为多个web服务器提供了一个共享的高性能缓存服务,在Memcached服务器上,又发展了根据hash算法来进行多台Memcached缓存服务的扩展,然后又出现了一致性hash来解决增加或减少缓存服务器导致重新hash带来的大量缓存失效的弊端。

  • 由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力。读写集中在一个数据库上让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离:Mysql主从读写分离,以提高读写性能和读库的可扩展性。Mysql的master-slave模式成为这个时候的网站标配了。在这里插入图片描述

  • 在Memcached的高速缓存,MySQL的主从复制,读写分离的基础之上,这时MySQL主库的写压力开始出现瓶颈,而数据量的持续猛增,由于MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替MyISAM。同时,开始流行使用分表分库来缓解写压力和数据增长的扩展问题。这个时候,分表分库成了一个热门技术,是面试的热门问题也是业界讨论的热门技术问题。也就在这个时候,MySQL推出了还不太稳定的表分区:分表分库+水平拆分+mysql集群 。这也给技术实力一般的公司带来了希望。虽然MySQL推出了MySQL Cluster集群,但性能也不能很好满足互联网的要求,只是在高可靠性上提供了非常大的保证。在这里插入图片描述

  • MySQL数据库也经常存储一些大文本字段,导致数据库表非常的大,在做数据库恢复的时候就导致非常的慢,不容易快速恢复数据库。比如1000万4KB大小的文本就接近40GB的大小,如果能把这些数据从MySQL省去,MySQL将变得非常的小。关系数据库很强大,但是它并不能很好的应付所有的应用场景。MySQL的扩展性差(需要复杂的技术来实现),大数据下IO压力大,表结构更改困难,正是当前使用MySQL的开发人员面临的问题。

  • 今天我们可以通过第三方平台(如:Google,Facebook等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。我们如果要对这些用户数据进行挖掘,那SQL数据库已经不适合这些应用了, NoSQL数据库的发展也却能很好的处理这些大的数据。

3V+3高:

  • 大数据时代的3V:
    ①海量Volume
    ②多样Variety
    ③实时Velocity
  • 互联网需求的3高:
    ①高并发
    ②高可扩
    ③高性能

传统RDBMS VS NOSQL:

  • 传统RDBMS:
    关系型数据库和非关系型数据库都是讲述的文件内部的逻辑结构。
    关系型数据库:指采用了关系模型来组织数据的数据库。
    关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
    ④优点:
    <1>易于维护:都是使用表结构,格式一致;
    <2>使用方便:SQL语言通用,可用于复杂查询;
    <3>复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。
    ⑤缺点:
    <1>读写性能比较差,尤其是海量数据的高效率读写;
    <2>固定的表结构,灵活度稍欠;
    <3>高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。

  • NoSQL:
    非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等。
    ②优点:
    <1>格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
    <2>速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘。
    <3>高扩展性。
    <4>成本低:nosql数据库部署简单,基本都是开源软件。
    ③缺点:
    <1>不提供sql支持,学习和使用成本较高;
    <2>无事务处理;
    <3>数据结构相对复杂,复杂查询方面稍欠。

NoSQL数据模型简介:

  • KV键值:键值对。

  • Bson:Bson()是一种类json的一种二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象。

  • 列族:顾名思义是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。在这里插入图片描述

  • 图形:在这里插入图片描述

NoSQL数据库的四大分类简介:

  • KV键值:
    ①典型介绍:redis
  • 文档型数据库:bson格式比较多
    ①典型介绍:CouchDB,MongoDB
  • 列存储数据库:分布式文件系统
    ①典型介绍: Cassandra,HBase
  • 图关系数据库:它不是放图形的,放的是关系比如:朋友圈社交网络、广告推荐系统。
    ①典型介绍: Neo4J, InfoGrid
  • 四者对比:
    在这里插入图片描述

NOSQL详解

NoSQL经典应用:

  • 当下的应用是sql和nosql一起使用。
  • 架构发展历程:
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • 多数据源多数据类型的存储问题:
    在这里插入图片描述
  • 阿里巴巴中文站商品信息如何存放:
    ①商品基本信息:
    <1>使用关系型数据库
    <2>mysql/oracle目前淘宝在去O化(也即拿掉Oracle)
    ②商品描述、详情、评价信息(多文字类):
    <1>多文字信息描述类,IO读写性能变差
    <2>因此使用文档数据库MongDB中
    ③商品的图片:
    <1>使用分布式的文件系统
    1、淘宝自己的TFS
    2、Google的GFS
    3、Hadoop的HDFS
    ④商品的关键字:
    <1>使用搜索引擎
    <2>淘宝内用ISearch
    ⑤商品的波段性的热点高频信息:
    <1>使用内存数据库
    <2>Tair、Redis、Memcache
    ⑥商品的交易、价格计算、积分累计:
    <1>使用外部系统,外部第3方支付接口
    <2>支付宝
  • 难点:
    ①数据类型多样性
    ②数据源多样性和变化重构
    ③数据源改造而数据服务平台不需要大面积重构
  • 解决办法:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

TFS概述:

  • TFS(Taobao File System)是一个高可扩展、高可用、高性能、面向互联网服务的分布式文件系统, 主要针对海量的非结构化数据,它构筑在普通的Linux机器集群上,可为外部提供高可靠和高并发的存储访问。TFS为淘宝提供海量小文件存储,通常文件大小不超过1M,满足了淘宝对小文件存储的需求,被广泛地应用在淘宝各项应用中。它采用了HA架构和平滑扩容,保证了整个文件系统的可用性和扩展性。同时扁平化的数据组织结构,可将文件名映射到文件的物理地址,简化了文件的访问流程,一定程度上为TFS提供了良好的读写性能。

Cobar与myscat的区别:

  • Cobar概述:
    ①是由 Alibaba 开源的 MySQL 分布式处理中间件,它可以在分布式的环境下看上去像传统数据库一样提供海量数据服务。
    ②Cobar 架构:在这里插入图片描述③Cobar 解决的问题:
    <1>分布式:Cobar 的分布式主要是通过将表放入不同的库来实现。
    <2>Cobar 支持将一张表水平拆分成多份分别放入不同的库来实现表的水平拆分。
    <3>Cobar 也支持将不同的表放入不同的库。
    <4>多数情况下,用户会将以上两种方式混合使用。
  • myscat概述:
    ①mycat来自2013年阿里的Cobar的改良版, 截至2015年, 成为大多数公司的数据解决方案
    ②2013年阿里的Cobar在某大型项目中使用过程中发现存在一些比较严重的问题,于是第一代改良版——Mycat诞生。
    ③一个用于MySQL读写分离和与数据切分的高可用中间件
    ④一个模拟为MySQLServer的超级数据库代理
    ⑤一个能平滑扩展支持1000亿大表的分布式数据库系统 (普通单表1kw以下)
    ⑥一个可管控多种关系数据库的数据库路由器

分布式数据库中CAP原理CAP+BASE:

  • 传统的ACID分别是什么:
    ①A (Atomicity) 原子性
    ②C (Consistency) 一致性
    ③I (Isolation) 独立性
    ④D (Durability) 持久性
  • 分布式数据库中CAP:
    C:Consistency(强一致性)
    A:Availability(可用性)
    P:Partition tolerance(分区容错性)
  • CAP的3进2:
    CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。
    而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。
    所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。
    ④选择:
    <1>CA:传统Oracle数据库
    <2>AP:大多数网站架构的选择
    <3>CP:Redis、Mongodb
  • 注意:分布式架构的时候必须做出取舍。一致性和可用性之间取一个平衡。多余大多数web应用其实并不需要强一致性。因此牺牲C换取A,这是目前分布式数据库产品的方向。
  • 一致性与可用性的决择:
    ①对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地
    ②数据库事务一致性需求,很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低, 有些场合对写一致性要求并不高。允许实现最终一致性。
    ③数据库的写实时性和读实时性需求,对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,比方说发一条消息之后,过几秒乃至十几秒之后,我的订阅者才看到这条动态是完全可以接受的。
    ④对复杂的SQL查询,特别是多表关联查询的需求。任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的报表查询,特别是SNS类型的网站,从需求以及产品设计角度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。

ehcache、memcache、redis三大缓存比较:

  • EhCache:EhCache是一个java实现的开源分布式缓存,缓存方式有内存和磁盘两种方式,所以不用担心容量的问题,同时也可以作为java容器内部的缓存方案。当作为集群方式使用时,需要通过RMI或者API的方式调用,并且是鼎鼎大名的Hibernate的默认缓存实现。
  • Memcache:Memcache是多线程,非阻塞IO复用的网络模型,数据结构就是简单的key-value,memcache最经典的是其内存管理方式,使用了Slab Allocation机制管理内存,内存划分为预先规定的大小,不足内存块大小的会放入最小能容下数据的内存块,并且对key有250字节的大小限制,value默认是1m(可调整)。对于缓存内数据的并发问题,memcache提供了cas命令,memcache的集群方式是建立在客户端的,服务端不支持集群化,客户端根据需要采用一致性哈希算法上线缓存数据的分布式存储。并且memcache没有提供鼓掌容灾的方案,需要客户端考虑和实现。
  • Redis:Redis是新起之秀,发展速度非常快,Redis是一个单进程的缓存服务,说单进程是说处理客户端请求是单进程方式进行的,内部操作和持久化、备份等其实还是fock出子进程去操作的。单进程比多进程的优点就是可以简化内部实现,同时不需要担心并发问题,避免了锁这种耗时的机制,也省去了线程切换等开销。再加上redis是内存操作,所以速度非常快,单进程加上多路I/O复用技术是完全可以满足需要的。redis有丰富的数据结构,除了kv还有list,set,zset,hash等。同时支持RDB和AOF两种持久化方式。有官方的集群方案和容灾方案,虽然不支持cas操作,但是支持弱级别的事务。功能要比memcache完善的多,但是也正因如此,性能上会比memcache差一些。同时因为是单进程,使用时需要特别注意性能低的命令和缓存数据的大小,否则一不留神会造成整个集群都阻塞住。
  • 链接:ehcache、memcache、redis三大缓存比较

Redis简介

Redis是什么:

  • Redis:REmote DIctionary Server(远程字典服务器)
  • 是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器。
  • Redis 与其他 key - value 缓存产品有以下三个特点:
    ①Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
    ②Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
    ③Redis支持数据的备份,即master-slave模式的数据备份。

Redis能干嘛:

  • 内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务。
  • 取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
  • 模拟类似于HttpSession这种需要设定过期时间的功能
  • 发布、订阅消息系统
  • 定时器、计数器

RedisLinux版安装:

在这里插入图片描述
Linux下gcc/g++、make和cmake的区别:

  • 文本程序到可执行文件生成无论在什么平台大致分为以下几个部分:
    ①用编辑器编写源代码,如.c文件。
    ②用编译器编译代码生成目标文件,如.o。
    ③用链接器连接目标代码生成可执行文件,如.exe。
  • Linux平台下,.o文件一般是通过编译的但还未链接的目标文件,.out文件一般都是经过相应的链接产生的可执行文件(linux下)。当然这是一般情况下人们这么设置,而真正的,在linux中.o通常保存的是可执行代码 ,至于可执行文件则没有规定扩展名,用的是文件属性位来决定的是否可执行。在chmod中设置。
  • 我们知道编译和链接阶段是靠g++和gcc编辑器来完成,这两个编译阶段是相同的,但是链接阶段g++默认链接c++库,所以一般情况下用gcc编译c文件,而g++编译cpp文件。当然g++也可以编译c文件,而gcc编译cpp文件则需要在后面加上参数-lstdc++,作用就是链接c++库。
  • 但是如果编译和链接的阶段如果源文件太多,一个一个编译时就会特别麻烦,于是人们想到,为什么不设计一种类似批处理的程序,来批处理编译源文件呢,于是就有了make工具,它是一个自动化编译工具,你可以使用一条命令实现完全编译。但是你需要编写一个规则文件,make依据它来批处理编译,这个文件就是makefile,所以编写makefile文件也是一个程序员所必备的技能。
  • 对于一个大工程,编写makefile实在是件复杂的事,于是人们又想,为什么不设计一个工具,读入所有源文件之后,自动生成makefile呢,于是就出现了cmake工具,它能够输出各种各样的makefile或者project文件,从而帮助程序员减轻负担。但是随之而来也就是编写cmakelist文件,它是cmake所依据的规则。所以在编程的世界里没有捷径可走,还是要脚踏实地的。
  • 原文件—cmakelist —cmake —makefile —make —生成可执行文件(make中则包含了多条链接以及gcc/g++编译语句)。

Redis启动后杂项基础知识讲解:
在这里插入图片描述

Redis数据类型

Redis的五大数据类型:

  • String(字符串):string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M

  • Hash(哈希,类似java里的Map):Redis hash 是一个键值对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。类似Java里面的Map<String,Object>

  • List(列表):Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。它的底层实际是个链表

  • Set(集合):Redis的Set是string类型的无序集合。它是通过HashTable实现实现的。

  • Zset(sorted set:有序集合):Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。

redis常见数据类型操作命令:

  • 链接:Redis指令
  • Redis 键(key):
    在这里插入图片描述
  • Redis字符串(String):
    在这里插入图片描述
  • Redis列表(List):
    在这里插入图片描述在这里插入图片描述
  • Redis集合(Set):
    在这里插入图片描述
  • Redis哈希(Hash):
    在这里插入图片描述
  • Redis有序集合Zset(sorted set):
    在这里插入图片描述在这里插入图片描述

配置文件redis.conf

配置文件redis.conf的位置:
在这里插入图片描述

Units单位:

  • 配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bit
  • 对大小写不敏感
    在这里插入图片描述

INCLUDES包含:

  • 和我们的Struts2配置文件类似,可以通过includes包含,redis.conf可以作为总闸,包含其他
  • 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
    include /path/to/local.conf

在这里插入图片描述

GENERAL通用:

  • Daemonize:
    Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
    daemonize no

  • Pidfile:
    当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
    pidfile /var/run/redis.pid

  • Port:
    指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字
    port 6379

  • Tcp-backlog:
    设置tcp的backlog,backlog其实是一个连接队列,backlog队列总和=未完成三次握手队列 + 已经完成三次握手队列。
    在高并发环境下你需要一个高backlog值来避免慢客户端连接问题。注意Linux内核会将这个值减小到/proc/sys/net/core/somaxconn的值,所以需要确认增大somaxconn和tcp_max_syn_backlog两个值
    来达到想要的效果

  • Timeout:
    当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
    timeout 300

  • Bind :
    绑定的主机地址

  • Tcp-keepalive:
    单位为秒,如果设置为0,则不会进行Keepalive检测,建议设置成60

  • Loglevel:
    指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
    loglevel verbose

  • Logfile:
    日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
    logfile stdout

  • Syslog-enabled:
    是否把日志输出到syslog中

  • Syslog-ident:
    指定syslog里的日志标志

  • Syslog-facility:
    指定syslog设备,值可以是USER或LOCAL0-LOCAL7

  • Databases:
    设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id
    databases 16

SNAPSHOTTING快照:

  • Save:
    ① 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合。
    格式:save 秒钟 写操作次数
    RDB是整个内存的压缩过的Snapshot,RDB的数据结构,可以配置复合的快照触发条件,
    默认:是1分钟内改了1万次,或5分钟内改了10次,或15分钟内改了1次。
    在这里插入图片描述
    ②如果想禁用RDB持久化的策略,只要不设置任何save指令,或者给save传入一个空字符串参数也可以。在这里插入图片描述

  • Stop-writes-on-bgsave-error:
    如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制。
    在这里插入图片描述

  • rdbcompression:
    rdbcompression:对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。在这里插入图片描述

  • rdbchecksum:
    rdbchecksum:在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
    在这里插入图片描述

  • dbfilename:
    指定本地数据库文件名,默认值为dump.rdb
    dbfilename dump.rdb

  • dir:
    指定本地数据库存放目录
    dir ./

REPLICATION复制:

  • 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
    slaveof<masterip> <masterport>

SECURITY安全:

  • 访问密码的查看、设置和取消

  • 当master服务设置了密码保护时,slav服务连接master的密码
    masterauth <master-password>

  • 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
    requirepass foobared
    在这里插入图片描述

LIMITS限制:

  • Maxclients:
    设置redis同时可以与多少个客户端进行连接。默认情况下为10000个客户端。当你无法设置进程文件句柄限制时,redis会设置为当前的文件句柄限制值减去32,因为redis会为自身内部处理逻辑留一些句柄出来。如果达到了此限制,redis则会拒绝新的连接请求,并且向这些连接请求方发出“max number of clients reached”以作回应。

  • Maxmemory:
    设置redis可以使用的内存量。一旦到达内存使用上限,redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定。如果redis无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,
    那么redis则会针对那些需要申请内存的指令返回错误信息,比如SET、LPUSH等。
    但是对于无内存申请的指令,仍然会正常响应,比如GET等。如果你的redis是主redis(说明你的redis有从redis),那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的情况下,才不用考虑这个因素

  • Maxmemory-policy:
    (1)volatile-lru:使用LRU算法移除key,只对设置了过期时间的键
    (2)allkeys-lru:使用LRU算法移除key
    (3)volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键
    (4)allkeys-random:移除随机的key
    (5)volatile-ttl:移除那些TTL值最小的key,即那些最近要过期的key
    (6)noeviction:不进行移除。针对写操作,只是返回错误信息

  • Maxmemory-samples:
    设置样本数量,LRU算法和最小TTL算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小,
    redis默认会检查这么多个key并选择其中LRU的那个

APPEND ONLY MODE追加:

  • appendonly:
    指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no

  • appendfilename:
    指定更新日志文件名,默认为appendonly.aof
    appendfilename appendonly.aof

  • Appendfsync:
    ① Always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
    ② Everysec:出厂默认推荐,异步操作,每秒记录 如果一秒内宕机,有数据丢失
    ③ No
    在这里插入图片描述

  • No-appendfsync-on-rewrite:
    重写时是否可以运用Appendfsync,用默认no即可,保证数据安全性。

  • Auto-aof-rewrite-min-size:
    设置重写的基准值

  • Auto-aof-rewrite-percentage:
    设置重写的基准值

Redis的持久化

总结:

  • RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储
  • AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
  • 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
  • 同时开启两种持久化方式:
    ①在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,
    因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
    ②RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。不能只使用AOF因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。
  • 性能建议:
    ①因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。
    ②如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
    ③如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构

RDB(Redis DataBase)简介:

  • 在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
  • Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
  • Fork:
    Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
    Rdb 保存的是dump.rdb文件
    配置位置对应上面的SNAPSHOTTING快照
  • 如何触发RDB快照:
    ①配置文件中默认的快照配置:可以冷拷贝后重新使用可以cp dump.rdb dump_new.rdb
    ②命令save或者是bgsave:
    <1>Save:save时只管保存,其它不管,全部阻塞。
    <2>BGSAVE:Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间。
    ③执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义。
  • 如何恢复:
    ①将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可
    ②CONFIG GET dir获取目录
  • 优势:
    ①适合大规模的数据恢复
    ②对数据完整性和一致性要求不高
  • 劣势:
    ①在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改
    ②Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
  • 如何停止:动态所有停止RDB保存规则的方法:"redis-cli config set save "
  • 总结:
    在这里插入图片描述

AOF(Append Only File)简介:

  • 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
  • Aof保存的是appendonly.aof文件,配置位置对应上面的APPEND ONLY MODE追加。
  • AOF启动/修复/恢复:
    ①正常恢复:
    <1>启动:设置Yes-------修改默认的appendonly no,改为yes
    <2>将有数据的aof文件复制一份保存到对应目录(config get dir)
    <3>恢复:重启redis然后重新加载
    ②异常恢复:
    <1>启动:设置Yes--------修改默认的appendonly no,改为yes
    <2>修复:Redis-check-aof --fix进行修复
    <3>恢复:重启redis然后重新加载
  • Rewrite:
    ①简介:AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof。
    ②重写原理:AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
    ③触发机制:Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
  • 优势:
    ①每修改同步:appendfsync always 同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
    ②每秒同步:appendfsync everysec 异步操作,每秒记录 如果一秒内宕机,有数据丢失
    ③不同步:appendfsync no 从不同步
  • 劣势:
    ①相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb
    ②Aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同
  • 总结:
    在这里插入图片描述

Redis的事务

简介:

  • 可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

作用:

  • 一个队列中,一次性、顺序性、排他性的执行一系列命令。

具体操作:

  • 常用命令:
    在这里插入图片描述
  • Case1:正常执行:
    ① 正常执行EXEC()
  • Case2:放弃事务
    ① 执行了DISCARD()
  • Case3:全体连坐:
    ① 有一个命令编译出错了,导致全部失效
  • Case4:冤头债主:
    ① 有一个命令执行过程中出错了,其他执行成功,但出错的失效了。
  • Case5:watch监控:
    ①Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行。
    ②通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。

悲观锁/乐观锁/CAS(Check And Set):

  • 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
  • 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,
    乐观锁策略:提交版本必须大于记录当前版本才能执行更新。

三个阶段:

  • 开启:以MULTI开始一个事务。
  • 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面。
  • 执行:由EXEC命令触发事务。

三个特性:

  • 单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题。
  • 不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。

Redis的发布订阅

简介:

  • 进程间的一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
  • 类似于MQ的主题模式-只能消费订阅之后发布的消息,一个消息可以被多个订阅者消费。
  • 订阅者可以订阅一个或者多个频道(channel),而发布者可以向指定的频道(channel)发送消息,所有订阅此频道的订阅者都会收到此消息。
  • 适合用于所有消费者同时消费的业务。

订阅/发布消息图:
在这里插入图片描述

命令:
在这里插入图片描述

Redis的复制(Master/Slave)

简介:

  • 行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主。

作用:

  • 读写分离
  • 容灾恢复

具体操作:

  • 配从(库)不配主(库)。

  • 从库配置:slaveof 主库IP 主库端口
    ①每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件。
    ②Info replication查看当前身份

  • 常用三招
    一主二仆
    薪火相传:
    1、上一个Slave可以是下一个slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力。
    2、中途变更转向:会清除之前的数据,重新建立拷贝最新的。
    3、Slaveof 新主库IP 新主库端口
    反客为主
    SLAVEOF no one 使当前数据库停止与其他数据库的同步,转成主数据库

复制原理:

  • Slave启动成功连接到master后会发送一个sync命令。
  • Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步。
  • 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
  • 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步。
  • 但是只要是重新连接master,一次完全同步(全量复制)将被自动执行。

哨兵模式(sentinel):

  • 反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
  • 步骤:
    ①自定义的/myredis目录下新建sentinel.conf文件,名字绝不能错
    ② 配置哨兵,填写内容
    格式: sentinel monitor 被监控数据库名字(自己起名字) IP地址 数字
    (数字表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机)
    ③启动哨兵Redis-sentinel /myredis/sentinel.conf
    ④当原有的master挂了,会投票新选
    ⑤如果之前的master重启回来,不会冲突,之前的master需要重新配置。
  • 一组sentinel能同时监控多个Master。

复制的缺点:

  • 复制延时:由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

Redis总结

总结:

在这里插入图片描述

Redis常见的应用场景解析:

  • 秒杀和Redis的结合:
    ①提前预热数据,放入Redis
    ②商品列表放入Redis List
    ③商品的详情数据 Redis hash保存,设置过期时间
    ④商品的库存数据Redis sorted set保存
    ⑤用户的地址信息Redis set保存
    ⑥订单产生扣库存通过Redis制造分布式锁,库存同步扣除
    ⑦订单产生后发货的数据,产生Redis list,通过消息队列处理
    ⑧秒杀结束后,再把Redis数据和数据库进行同步
  • 点赞与Redis结合:
    ①需求:
    <1>显示点赞数量
    <2>判断用户是否点过赞,用于去重,必须的判断
    <3>显示个人点赞列表,一般在用户中心
    <4>显示文章点赞列表
    ②链接:点赞功能,用 MySQL 还是 Redis ?
  • 使用场景汇总:
    ①链接:跟我一起学Redis之五种基本类型及其应用场景举例(干了6个小时)
    在这里插入图片描述

Redis命令:

  • 链接:Redis 常用操作命令,非常详细!
  • 注意:
    INCR key:将key中存储的数字值增一。
    <1>如果key不存在,那么key的值会先被初始化为0,然后再执行INCR操作。
    <2>如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
    <3>本操作的值限制为64位(bit)有符号数字表示之内。
    <4>这是一个针对字符串的操作,因为redis没有专用的整数类型,所以key内存储的字符串被解释为十进制64位有符号整数来执行INCR操作。
cmd访问redis
redis-cli.exe -h 127.0.0.1 -p 6379


key
    keys * 获取所有的key
    select 0 选择第一个库
    move myString 1 将当前的数据库key移动到某个数据库,目标库有,则不能移动
    flush db      清除指定库
    randomkey     随机key
    type key      类型
    
    set key1 value1 设置key
    get key1    获取key
    mset key1 value1 key2 value2 key3 value3
    mget key1 key2 key3
    del key1   删除key
    exists key      判断是否存在key
    expire key 10   10过期
    pexpire key 1000 毫秒
    persist key     删除过期时间

string
    set name cxx
    get name
    getrange name 0 -1        字符串分段
    getset name new_cxx       设置值,返回旧值
    mset key1 key2            批量设置
    mget key1 key2            (MANY set)批量获取
    setnx key value           (SET if Not eXists)不存在就插入(not exists)
    setex key time value      (set expire)过期时间
    setrange key index value  从index开始替换value
    incr age        (increasing)递增
    incrby age 10   (increasing by)递增
    decr age        (decresing)递减
    decrby age 10   (decresing by)递减
    incrbyfloat     增减浮点数
    append          追加
    strlen          长度
    getbit/setbit/bitcount/bitop    位操作
    ttl key			(Time To Live)查看指定key还剩余多长时间
    
hash
    hset myhash name cxx
    hget myhash name
    hmset myhash name cxx age 25 note "i am notes"
    hmget myhash name age note   
    hgetall myhash               获取所有的
    hexists myhash name          是否存在
    hsetnx myhash score 100      设置不存在的
    hincrby myhash id 1          递增
    hdel myhash name             删除
    hkeys myhash                 只取key
    hvals myhash                 只取value
    hlen myhash                  长度

list
    lpush mylist a b c  左插入
    rpush mylist x y z  右插入
    lrange mylist 0 -1  数据集合
    lpop mylist  弹出元素
    rpop mylist  弹出元素
    llen mylist  长度
    lrem mylist count value  删除前count(数字)次出现的值为value(元素)
    lindex mylist 2          指定索引的值
    lset mylist 2 n          索引设值
    ltrim mylist 0 4         删除key
    linsert mylist before a  插入
    linsert mylist after a   插入
    rpoplpush list list2     转移列表的数据
    blpop key [key1 ...] timeout	(block left pop)从指定key列表中左边取出第一个值,若列表中没有元素就等待timeout时间,如果timeout为0就一直等待。
	brpop key [key1 ...] timeout	(block right pop)从指定key列表中右边取出第一个值,若列表中没有元素就等待timeout时间,如果timeout为0就一直等待。
    
set
    sadd myset redis 
    smembers myset       数据集合
    srem myset set1         删除
    sismember myset set1 判断元素是否在集合中
    scard key_name       个数
    sdiff | sinter | sunion 操作:集合间运算:差集 | 交集 | 并集
    srandmember          随机获取集合中的元素
    spop                 从集合中弹出一个元素
    
zset
    zadd zset 1 one
    zadd zset 2 two
    zadd zset 3 three
    zincrby zset 1 one              增长分数
    zscore zset two                 获取分数
    zrange zset 0 -1 withscores     范围值
    zrangebyscore zset 10 25 withscores 指定范围的值
    zrangebyscore zset 10 25 withscores limit 1 2 分页
    Zrevrangebyscore zset 10 25 withscores  指定范围的值
    zcard zset  元素数量
    Zcount zset 获得指定分数范围内的元素个数
    Zrem zset one two        删除一个或多个元素
    Zremrangebyrank zset 0 1  按照排名范围删除元素
    Zremrangebyscore zset 0 1 按照分数范围删除元素
    Zrank zset 0 -1    分数最小的元素排名为0
    Zrevrank zset 0 -1  分数最大的元素排名为0
    Zinterstore
    zunionstore rank:last_week 7 rank:20150323 rank:20150324 rank:20150325  weights 1 1 1 1 1 1 1
    
    
排序:
    sort mylist  排序
    sort mylist alpha desc limit 0 2 字母排序
    sort list by it:* desc           by命令
    sort list by it:* desc get it:*  get参数
    sort list by it:* desc get it:* store sorc:result  sort命令之store参数:表示把sort查询的结果集保存起来

订阅与发布:
    订阅频道:subscribe chat1
    发布消息:publish chat1 "hell0 ni hao"
    查看频道:pubsub channels
    查看某个频道的订阅者数量: pubsub numsub chat1
    退订指定频道: unsubscrible chat1   , punsubscribe java.*
    订阅一组频道: psubscribe java.*
    
redis事物:
     隔离性,原子性, 
     步骤:  开始事务,执行命令,提交事务
             multi  //开启事务
             sadd myset a b c
             sadd myset e f g
             lpush mylist aa bb cc
             lpush mylist dd ff gg

服务器管理
    dump.rdb
    appendonly.aof
    //BgRewriteAof 异步执行一个aop(appendOnly file)文件重写
    会创建当前一个AOF文件体积的优化版本
    
    //BgSave 后台异步保存数据到磁盘,会在当前目录下创建文件dump.rdb
    //save同步保存数据到磁盘,会阻塞主进程,别的客户端无法连接
    
    //client kill 关闭客户端连接
    //client list 列出所有的客户端
    
    //给客户端设置一个名称
      client setname myclient1
      client getname
      
     config get port
     //configRewrite 对redis的配置文件进行改写

rdb
save 900 1
save 300 10
save 60 10000

aop备份处理
appendonly yes 开启持久化
appendfsync everysec 每秒备份一次

命令:
bgsave异步保存数据到磁盘(快照保存)
lastsave返回上次成功保存到磁盘的unix的时间戳
shutdown同步保存到服务器并关闭redis服务器
bgrewriteaof文件压缩处理(命令)

Redis key设计技巧:

  • 总结:
    把表名转换为key前缀,如tag:
    把第二段放置用于区分key的字段,对应msyql中主键的列名,如user_id
    第三段放置主键值,如2,3,4
    第四段写存储的列名
用户表uesr,转换为key-value存储
user_id		user_name	email
9			lily		lily@qq.com
set user:user_id:9:user_name lily
set user:user_id:9:email	lily@qq.com
#查询这个用户
keys user:user_id:9*
  • 注意:
    在关系型数据中,除主键外,还有可能其他列也会参与查询。
    <1>如上表中,user_name也是很频繁查询的,往往这种列也是加了索引的。
    <2>转换到key-value数据中,则也要相应的生成一条按照该列为主的key-value
    <3>这样我们可以根据user_name:lily:user_id查询出user_id为9,再查user_id:9:email。完成了根据用户名查询用户信息。
set user_name:lily:user_id 9

Redis的key:

  • Redis的key的长度没有限制.key是按照hash查找的 ,当然越小 ,理论上越快 。并没有必然要多长的限制 ,尽量短就可以了!
  • Rediskey值是二进制安全的,这意味着可以用任何二进制序列作为key值,从形如”foo”的简单字符串到一个JPEG文件的内容都可以。空字符串也是有效key值。
  • 关于key的几条规则:太长的键值不是个好主意,例如1024字节的键值就不是个好主意,不仅因为消耗内存,而且在数据中查找这类键值的计算成本很高。太短的键值通常也不是好主意,如果你要用”u:1000:pwd”来代替”user:1000:password”,这没有什么问题,但后者更易阅读,并且由此增加的空间消耗相对于key object和value object本身来说很小。
  • 当然,没人阻止您一定要用更短的键值节省一丁点儿空间。最好坚持一种模式。例如:”object-type:id:field”就是个不错的注意,像这样”user:1000:password”。我喜欢对多单词的字段名中加上一个点,就像这样:”comment:1234:reply.to”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值