莫愁前路无知己,天下谁人不识Redis
1. 数据库小知识
1.1 什么是数据库
数据库是“按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合。数据库是以一定方式储存在一起、能与多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合,可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据进行新增、查询、更新、删除等操作。
1.2 数据库的种类
数据库分为关系型数据库和非关系型数据库。
1.3 关系型数据库
关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。
常见的关系型数据库:MySQL、Oracle、Microsoft SQL Server、DB2、Microsoft Access
关系型数据库遵循ACID规则:
1、A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
2、C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。
3、I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
比如现在有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。
4、D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
1.4 RDBMS
RDBMS 即关系数据库管理系统(Relational Database Management System)
1.4.1 特点
- 1.数据以表格的形式出现
- 2.每行为各种记录名称
- 3.每列为记录名称所对应的数据域
- 4.许多的行和列组成一张表单
- 5.若干的表单组成database
1.4.2 术语
- 数据库: 数据库是一些关联表的集合。
- 数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
- 列: 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。
- 行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
- 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
- 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
- 外键:外键用于关联两个表。
- 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
- 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
- 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致
性。
1.5 非关系型数据库
NoSQL 是 Not Only SQL 的缩写,意即"不仅仅是SQL"的意思,泛指非关系型的数据库。强调Key-Value Stores和文档数据库的优点,而不是单纯的反对RDBMS。
1.6 关系型数据库与非关系型数据库对比
关系型数据库
关系型数据库的特性
1、关系型数据库,是指采用了关系模型来组织数据的数据库;
2、关系型数据库的最大特点就是事务的一致性;
3、简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
关系型数据库的优点
1、容易理解:二维表结构是非常贴近逻辑世界一个概念,关系模型相对网状、层次等其他模型来说更容易理解;
2、使用方便:通用的SQL语言使得操作关系型数据库非常方便;
3、易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率;
4、支持SQL,可用于复杂的查询。关系型数据库的缺点
1、为了维护一致性所付出的巨大代价就是其读写性能比较差;
2、固定的表结构;
3、高并发读写需求;
4、海量数据的高效率读写;
非关系型数据库
非关系型数据库的特性
1、使用键值对存储数据;
2、分布式;
3、一般不支持ACID特性;
4、非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。非关系型数据库的优点
1、无需经过sql层的解析,读写性能很高;
2、基于键值对,数据没有耦合性,容易扩展;
3、存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,而关系型数据库则只支持基础类型。非关系型数据库的缺点
1、不提供sql支持,学习和使用成本较高;
2、无事务处理,附加功能bi和报表等支持也不好;
2. Redis 简介
2.1 什么是Redis
Redis是开源的(BSD许可)内存数据结构存储,用作数据库,缓存和消息代理。它支持数据结构,例如 字符串,哈希,列表,集合,带范围查询的排序集合,位图,超日志,带有半径查询的流空间索引和流。Redis具有内置的复制,Lua脚本,LRU逐出,事务和不同级别的磁盘持久性,并通过以下方式提供高可用性Redis Sentinel和Redis Cluster自动分区。
您可以 对这些类型运行原子操作,例如追加到字符串; 在哈希中增加值 ; 将元素推送到列表 ; 计算集的交集, 并集和差 ; 或获得排序集中排名最高的成员。
为了获得出色的性能,Redis使用 内存中的数据集。根据您的用例,您可以通过将数据集 偶尔转储到磁盘上,或者通过将每个命令附加到log来持久化它。如果只需要功能丰富的网络内存缓存,则可以选择禁用持久性。
Redis还支持琐碎的设置主从异步复制,具有非常快速的非阻塞式第一次同步,自动重新连接以及网络拆分中的部分重新同步。
其他功能包括:
菜鸟教程:https://www.runoob.com/redis/redis-tutorial.html
Redis官网:https://redis.io/
2.2 Redis优势
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
2.3 Redis应用场景
1.缓存(常用)
一般我们会在业务中经常会被查询,但是不经常被修改或者删除的热点数据作为缓存,以提高网站访问的速度,减少数据库查询的压力。
在对数据库的读写操作上,现实的情况往往是读比写的多好几倍。当发送SQL语句时,数据库就会去磁盘把读写对应的数据,而去磁盘读写时一个相对缓慢的过程,取到后需要放置内存中进行读写操作,最后返回结果。既然是在内存中进行读写操作,因此把数据直接放在内存中,就不需要频繁去磁盘进行读写操作了,而是直接操作内存的数据,进而提示了访问的速度,也减轻了数据库的压力。
举例子:存储用户的信息(比如微信个人的信息,微信号id是固定不变的,个人二维码也是不变的,性别,个性签名等),银行卡信息、热点新闻关键字、秒杀商品等
2、排行榜
很普遍的是各种数据库的数据并非存储在内存中,在按得分排序以及实时更新这些几乎每秒钟都需要更新的排行榜,用Rdis可以解决。
3.显示最新的项目列表
下面这个语句常用来显示最新项目列表,随着数据多了,查询毫无疑问会越来越慢。
SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10
在Web应用中,“列出最新的回复”之类的查询非常普遍,这通常会带来可扩展性问题。这令人沮丧,因为项目本来就是按这个顺序被创建的,但要输出这个顺序却不得不进行排序操作。
类似的问题就可以用Redis来解决。比如说,我们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论。
我们假设数据库中的每条评论都有一个唯一的递增的ID字段。
我们可以使用分页来制作主页和评论页,使用Redis的模板:
-每次新评论发表时,我们会将它的ID添加到一个Redis列表:
LPUSH latest.comments <ID>
-我们将列表裁剪为指定长度,因此Redis只需要保存最新的5000条评论:
LTRIM latest.comments 0 5000
-每次我们需要获取最新评论的项目范围时,我们调用一个函数来完成(使用伪代码):
FUNCTION get_latest_comments(start,num_items): id_list = redis.lrange("latest.comments",start,start+num_items-1) IF id_list.length < num_items id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...") END RETURN id_list END
这里我们做的很简单。在Redis中我们的最新ID使用了常驻缓存,这是一直更新的。但是我们做了限制不能超过5000个ID,因此我们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才需要去访问数据库。
我们的系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。
4.删除和过滤
我们可以使用LREM来删除评论。如果删除操作非常少,另一个选择是直接跳过评论条目的入口,报告说该评论已经不存在。
有些时候你想要给不同的列表附加上不同的过滤器。如果过滤器的数量受到限制,你可以简单的为每个不同的过滤器使用不同的Redis列表。毕竟每个列表只有5000条项目,但Redis却能够使用非常少的内存来处理几百万条项目。
5.按照用户投票和时间排序
排行榜的一种常见变体模式就像Reddit或Hacker News用的那样,新闻按照类似下面的公式根据得分来排序:
score = points / time^alpha
因此用户的投票会相应的把新闻挖出来,但时间会按照一定的指数将新闻埋下去。下面是我们的模式,当然算法由你决定。
模式是这样的,开始时先观察那些可能是最新的项目,例如首页上的1000条新闻都是候选者,因此我们先忽视掉其他的,这实现起来很简单。
- 每次新的新闻贴上来后,我们将ID添加到列表中,使用LPUSH + LTRIM,确保只取出最新的1000条项目。
- 有一项后台任务获取这个列表,并且持续的计算这1000条新闻中每条新闻的最终得分。计算结果由ZADD命令按照新的顺序填充生成列表,老新闻则被清除。这里的关键思路是排序工作是由后台任务来完成的。
6.过期项目处理
另一种常用的项目排序是按照时间排序。我们使用unix时间作为得分即可。
模式如下:
- 每次有新项目添加到我们的Redis数据库时,我们把它加入到排序集合中。这时我们用的是时间属性,current_time和time_to_live。
- 另一项后台任务使用ZRANGE…SCORES查询排序集合,取出最新的10个项目。如果发现unix时间已经过期,则在数据库中删除条目。
7.计数
8.特定时间内的特定项目
另一项对于其他数据库很难,但Redis做起来却轻而易举的事就是统计在某段特点时间里有多少特定用户访问了某个特定资源。比如我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章。
每次我获得一次新的页面浏览时我只需要这样做:
SADD page:day1:<page_id> <user_id>
当然你可能想用unix时间替换day1,比如time()-(time()%3600*24)等等。
想知道特定用户的数量吗?只需要使用SCARD page:day1:<page_id>。
需要测试某个特定用户是否访问了这个页面?SISMEMBER page:day1:<page_id>。
9.发布订阅
10.队列
11.分布式锁
12.分布式会话
13.社交网络
莫愁前路无知己,天下谁人不识Redis的更多相关文章
- VMware前路难测,多个厂家群雄逐鹿
以VMware为例,虚拟机巨头公布了第二财季报告所示,它第二财季收入同比增长13%,达到了21.7亿美元,而且该公司收入和每股收益均超出预期. 在人们高谈Salesforce.亚马逊等新兴云计算厂商取 ...
- [置顶] Android应用开发之版本更新你莫愁
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 今天我们学习如何实现Android应用的自动更新版本功能,这是在各种语言编写的应用中都 ...
- 安全之路 —— 无DLL文件实现远程线程注入
简介 在之前的章节中,笔者曾介绍过有关于远程线程注入的知识,将后门.dll文件注入explorer.exe中实现绕过防火墙反弹后门.但一个.exe文件总要在注入时捎上一个.dll文件着 ...
- 开源OA办公系统的“应用市场”,能够为协同办公开拓什么样的“前路”?
在我们的日常生活中,应用市场这个词,总是与智能手机划上等号,不管使用的是iPhone还是安卓,总会接触到手机上的APP应用市场,我们可以在应用市场中,选择自己所需要的APP应用软件,下载使用后,可以让 ...
- 安全之路 —— 无DLL文件实现远程进程注入
简介 在之前的章节中,笔者曾介绍过有关于远程线程注入的知识,将后门.dll文件注入explorer.exe中实现绕过防火墙反弹后门.但一个.exe文件总要在注入时捎上一个.dll文件着实是怪麻烦的,那 ...
- 面试前必须要知道的21道Redis面试题
1.使用redis有哪些好处? 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) 支持丰富数据类型,支持string,list,set,so ...
- 删库到跑路?还得看这篇Redis数据库持久化与企业容灾备份恢复实战指南
本章目录 0x00 数据持久化 1.RDB 方式 2.AOF 方式 如何抉择 RDB OR AOF? 0x01 备份容灾 一.备份 1.手动备份redis数据库 2.迁移Redis指定db-数据库 3 ...
- Python 之路:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
一.Memcached Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负债.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速 ...
- Python之路:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...
随机推荐
- 《深入理解java虚拟机》读书笔记一——第二章
第二章 Java内存区域与内存溢出异常 1.运行时数据区域 程序计数器: 当前线程所执行的字节码的行号指示器,用于存放下一条需要运行的指令. 运行速度最快位于处理器内部. 线程私有. 虚拟机栈: 描述 ...
- POJ2528Mayor's posters 线段树,离散化技巧
题意:一个坐标轴从1~1e7,每次覆盖一个区间(li,ri),问最后可见区间有多少个(没有被其他区间挡住的) 线段树,按倒序考虑,贴上的地方记为1,每次看(li,ri)这个区间是否全是1,全是1就说明 ...
- 打铁选手的 CDQ分治 刷题记录
BZOJ3262 模板题,三位偏序. 注意第一维排完序之后再给二三维排序的时候还是要考虑下第一维的:如果二三维都相等的话第一维小的要在前面 代码: #include <bits/stdc++.h ...
- PHP 实现时间戳转化为几分钟前、几小时前等格式
//发布时间提示 function get_last_time($time) { // 当天最大时间 $todayLast = strtotime(date('Y-m-d 23:59:59')); $ ...
- Mysql备份参数
--all-databases , -A 导出全部数据库. mysqldump -uroot -p --all-databases --all-tablespaces , -Y 导出全部表空间. my ...
- vue项目出现Module not found: Error: Can't resolve 'stylus-loader'错误解决方案
因为没有安装stylus和stylus-loader npm install stylus stylus-loader --save-dev 安装成功后,使用npm install重新建立依赖 打开项 ...
- 网易云信Duilib开发实践和Windows应用界面开发框架源码开源介绍
序言 Duilib介绍 Duilib是windows平台下的一款轻量级directUI开源库(遵循BSD协议),完全免费,可用于商业软件开发,只需在软件包里附上协议文件即可.Duilib可以简单方便地 ...
- maven scope 的作用
一: 1.Maven中的依赖作用范围概述 Maven中使用 scope 来指定当前包的依赖范围和依赖的传递性.常见的可选值有:compile, provided, runtime, test, sys ...
- jQuery添加/删除元素
jQuery append() 方法 jQuery append() 方法在被选元素的结尾插入内容(仍然该元素的内部). 追加前:<p>这是一个文本段落</p> $(" ...
- hadoop中遇到的各种错误记录
hadoop中namenode无法启动 转载链接:https://blog.csdn.net/love666666shen/article/details/74350358 使用pi ...