Redis的8个重要特性:

1.速度快正常情况下,Redis执行命令的速度非常快,官方给出的数字是读写性能可以达到10万/秒,当然这也取决于机器的性能,但这里先不讨论机器性能上的差异,只分析一下是什么造就了Redis除此之快的速度,可以大致归纳为以下四点:
·Redis的所有数据都是存放在内存中的,表1-1是谷歌公司2009年给出的各层级硬件执行速度,所以把数据放在内存中是Redis速度快的最主要原因。
·Redis是用C语言实现的,一般来说C语言实现的程序“距离”操作系统更近,执行速度相对会更快。
·Redis使用了单线程架构,预防了多线程可能产生的竞争问题。
·作者对于Redis源代码可以说是精打细磨,曾经有人评价Redis是少有的集性能和优雅于一身的开源代码。
2.基于键值对的数据结构服务器
几乎所有的编程语言都提供了类似字典的功能,例如Java里的map、Python里的dict,类似于这种组织数据的方式叫作基于键值的方式,与很多键值对数据库不同的是,Redis中的值不仅可以是字符串,而且还可以是具体的
4.简单稳定
Redis的简单主要表现在三个方面。首先,Redis的源码很少,早期版本的代码只有2万行左右,3.0版本以后由于添加了集群特性,代码增至5万行左右,相对于很多NoSQL数据库来说代码量相对要少很多,也就意味着普通的开发和运维人员完全可以“吃透”它。其次,Redis使用单线程模型,这样不仅使得Redis服务端处理模型变得简单,而且也使得客户端开发变得简单。最后,Redis不需要依赖于操作系统中的类库(例如Memcache需要依赖libevent这样的系统类库),Redis自己实现了事件处理的相关功能。
Redis虽然很简单,但是不代表它不稳定。以笔者维护的上千个Redis为例,没有 […]
6.持久化
通常看,将数据放在内存中是不安全的,一旦发生断电或者机器故障,重要的数据可能就会丢失,因此Redis提供了两种持久化方式:RDB和AOF,即可以用两种策略将内存的数据保存到硬盘中(如图1-1所示)
7.主从复制
Redis提供了复制功能,实现了多个相同数据的Redis副本(如图1-2所示),复制功能是分布式Redis的基础。第6章我们将对Redis的复制进行详细

1.3 Redis使用场景

1.缓存 缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力。Redis提供了键值过期时间设置,并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。可以这么说,一个合理的缓存设计能够为一个网站的稳定保驾护航。第11章将对缓存的设计与使用进行详细说明。
2.排行榜系统 排行榜系统几乎存在于所有的网站,例如按照热度排名的排行榜,按照发布时间的排行榜,按照各种复杂维度计算出的排行榜,Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。
3.计数器应用 计数器在网站中的作用至关重要,例如视频网站有播放数、电商网站有浏览数,为了保证数据的实时性,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。
4.社交网络 赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适合保存这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。
5.消息队列系统 消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功能基本可以满足。

1.3.2 Redis不可以做什么

我们可以站在数据规模和数据冷热的角度来进行分析。
站在数据规模的角度看,数据可以分为大规模数据和小规模数据,我们知道Redis的数据是存放在内存中的,虽然现在内存已经足够便宜,但是如果数据量非常大,例如每天有几亿的用户行为数据,使用Redis来存储的话,基本上是个无底洞,经济成本相当的高。
站在数据冷热的角度看,数据分为热数据和冷数据,热数据通常是指需要频繁操作的数据,反之为冷数据,例如对于视频网站来说,视频基本信息基本上在各个业务线都是经常要操作的数据,而用户的观看记录不一定是经常需要访问的数据,这里暂且不讨论两者数据规模的差异,单纯站在数据冷热的角度上看,视频信息属于热数据,用户观看记录属于冷数据。如果将这些冷数据放在Redis中,基本上是对于内存的一种浪费,但是对于一些热数据可以放在Redis中加速读写,也可以减轻后端存储的负载,可以说是事半功倍。

1.4 用好Redis的建议

1.切勿当作黑盒使用,开发与运维同样重要–如果不了解Redis的单线程模型,有些开发者会在有上千万个键的Redis上执行keys*操作,如果不了解持久化的相关原理,会在一个写操作量很大的Redis上配置自动保存RDB。
2.阅读源码

1.6 Redis重大版本
Redis借鉴了Linux操作系统对于版本号的命名规则:版本号第二位如果是奇数,则为非稳定版本(例如2.7、2.9、3.1),如果是偶数,则为稳定版本(例如2.6、2.8、3.0、3.2)。当前奇数版本就是下一个稳定版本的开发版,例如2.9版本是3.0版本的开发版本。所以我们在生产环境通常选取偶数版本的Redis,如果对于某些新的特性想提前了解和使用,可以选择最新的奇数版本。

1)Redis的8个特性:速度快、基于键值对的数据结构服务器、功能丰富、简单稳定、客户端语言多、持久化、主从复制、支持高可用和分布式。
2)Redis并不是万金油,有些场景不适合使用Redis进行开发。 3)开发运维结合以及阅读源码是用好Redis的重要方法。
4)生产环境中使用配置文件启动Redis。 5)生产环境选取稳定版本的Redis。
6)Redis3.0是重要的里程碑,发布了Redis官方的分布式实现Redis Cluster。


Redis这样设计有两个好处:第一,可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令,例如Redis3.2提供了quicklist,结合了ziplist和linkedlist两者的优势,为列表类型提供了一种更为优秀的内部编码实现,而对外部用户来说基本感知不到。第二,多种内部编码实现可以在不同场景下发挥各自的优势,例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,这时候Redis会根据配置选项将列表类型的内部实现转换为linkedlist。

2.1.3 单线程架构

Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务

本节首先通过多个客户端命令调用的例子说明Redis单线程命令处理机制,接着分析Redis单线程模型为什么性能如此之高,最终给出为什么理解单

其中第2步是重点要讨论的,因为Redis是单线程来处理命令的,所以一条命令从客户端达到服务端不会立刻被执行,所有命令都会进入一个队列中,然后逐个被执行。所以上面3个客户端命令的执行顺序是不确定的(如图2-4所示),但是可以确定不会有两条命令被同时执行(如图2-5所示),所以两条incr命令无论怎么执行最终结果都是2,不会产生并发问题,这就是Redis单线程的基本模型。但是像发送命令、返回结果、命令排队肯定不像描述的这么简单,Redis使用了I/O多路复用技术来解决I/O的问题,下一节将进行介绍


2.为什么单线程还能这么快
通常来讲,单线程处理能力要比多线程差,例如有10000斤货物,每辆车的运载能力是每次200斤,那么要50次才能完成,但是如果有50辆车,只要安排合理,只需要一次就可以完成任务。那么为什么Redis使用单线程模型会达会达到每秒万级别的处理能力呢?
第一,纯内存访问,Redis将所有数据放在内存中,内存的响应时长大约为100纳秒,这是Redis达到每秒万级别访问的重要基础。
第二,非阻塞I/O,Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间,如图2-6所示

第三,单线程避免了线程切换和竞态产生的消耗。
既然采用单线程就能达到如此高的性能,那么也不失为一种不错的选择,因为单线程能带来几个好处:第一,单线程可以简化数据结构和算法的实现。如果对高级编程语言熟悉的读者应该了解并发数据结构实现不但困难而且开发测试比较麻烦。第二,单线程避免了线程切换和竞态产生的消耗,对于服务端开发来说,锁和线程切换通常是性能杀手(备注:Redis使用单线程模型的原因)。
但是单线程会有一个问题:对于每个命令的执行时间是有要求的。如果某个命令执行过长,会造成其他命令的阻塞,对于Redis这种高性能的服务来说是致命的,所以Redis是面向快速执行场景的数据库。(备注:Redis使用单线程模型的缺点)。
单线程机制很容易被初学者忽视,但笔者认为Redis单线程机制是开发和运维人员使用和理解Redis的核心之一,随着后面的学习,相信读者会逐步理解。

2.2.3 典型使用场景

1.缓存功能
图2-10是比较典型的缓存使用场景,其中Redis作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用。下面伪代码模拟了图2-10的访问过程:

1)该函数用于获取用户的基础信息:

UserInfo getUserInfo(long id){
...
} 

2)首先从Redis获取用户信息:

// 定义键
userRedisKey = "user:info:" + id;
// 从Redis获取值
value = redis.get(userRedisKey);
if (value != null) {// 将值进行反序列化为UserInfo并返回结果userInfo = deserialize(value); return userInfo;
} 

开发提示

与MySQL等关系型数据库不同的是,Redis没有命令空间,而且也没有对键名有强制要求(除了不能使用一些特殊字符)。但设计合理的键名,有利于防止键冲突和项目的可维护性,比较推荐的方式是使用“业务名:对象名:id:[属性]”作为键名(也可以不是分号)。例如MySQL的数据库名为vs,用户表名为user,那么对应的键可以用”vs:user:1”,”vs:user:1:name”来表示,如果当前Redis只被一个业务使用,甚至可以去掉“vs:”。如果键名比较长,例如“user:{uid}:friends:messages:{mid}”,可以在能描述键含义的前提下适当减少键的长度,例如变为“u:{uid}:fr:m:{mid}”,从而减少由于键过长的内存浪费。

3)如果没有从Redis获取到用户信息,需要从MySQL中进行获取,并将结果回写到Redis,添加1小时(3600秒)过期时间:

// 从MySQL获取用户信息
userInfo = mysql.get(id);
// 将userInfo序列化, 并存入Redis
redis.setex(userRedisKey, 3600, serialize(userInfo));
// 返回结果
return userInfo 

整个功能的伪代码如下:

UserInfo getUserInfo(long id){userRedisKey = "user:info:" + idvalue = redis.get(userRedisKey);UserInfo userInfo;if (value != null) {userInfo = deserialize(value); } else {userInfo = mysql.get(id);if (userInfo != null)redis.setex(userRedisKey, 3600, serialize(userInfo));}return userInfo;
} 

2.计数
许多应用都会使用Redis作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。例如笔者所在团队的视频播放数系统就是使用Redis作为视频播放数计数的基础组件,用户每播放一次视频,相应的视频播放数就会自增1:

long incrVideoCounter(long id) {key = "video:playCount:" + id;return redis.incr(key);
} 

开发提示:实际上一个真实的计数系统要考虑的问题会很多:防作弊、按照不同维度计数,数据持久化到底层数据源等
3.共享Session
如图2-11所示,一个分布式Web服务将用户的Session信息(例如用户登录信息)保存在各自服务器中,这样会造成一个问题,出于负载均衡的考虑,分布式服务会将用户的访问均衡到不同服务器上,用户刷新一次访问可能会发现需要重新登录,这个问题是用户无法容忍的。

为了解决这个问题,可以使用Redis将用户的Session进行集中管理,如图2-12所示,在这种模式下只要保证Redis是高可用和扩展性的,每次用户更新或者查询登录信息都直接从Redis中集中获取。

4.限速
很多应用出于安全的考虑,会在每次进行登录时,让用户输入手机验证码,从而确定是否是用户本人。但是为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次,如图2-13所示。

此功能可以使用Redis来实现,下面的伪代码给出了基本实现思路:

phoneNum = "138xxxxxxxx";
key = "shortMsg:limit:" + phoneNum;
// SET key value EX 60 NX
isExists = redis.set(key,1,"EX 60","NX");
if(isExists != null || redis.incr(key) <=5){// 通过
}else{// 限速
} 

上述就是利用Redis实现了限速功能,例如一些网站限制一个IP地址不能在一秒钟之内访问超过n次也可以采用类似的思路。除了上面介绍的几种使用场景,字符串还有非常多的适用场景,开发人员可以结合字符串提供的相应命令充分发挥自己的想象力

StringRedisTemplate常用操作
2016年12月02日 15:31:22 标签:redis /spring 22278
[java] view plain copy
stringRedisTemplate.opsForValue().set("test", "100",60*10,TimeUnit.SECONDS);//向redis里存入数据和设置缓存时间
[java] view plain copy
stringRedisTemplate.boundValueOps("test").increment(-1);//val做-1操作
[java] view plain copy
stringRedisTemplate.opsForValue().get("test")//根据key获取缓存中的val
[java] view plain copy
stringRedisTemplate.boundValueOps("test").increment(1);//val +1
[java] view plain copy
stringRedisTemplate.getExpire("test")//根据key获取过期时间
[java] view plain copy
stringRedisTemplate.getExpire("test",TimeUnit.SECONDS)//根据key获取过期时间并换算成指定单位
[java] view plain copy
stringRedisTemplate.delete("test");//根据key删除缓存
[java] view plain copy
stringRedisTemplate.hasKey("546545");//检查key是否存在,返回boolean值
[java] view plain copy
stringRedisTemplate.opsForSet().add("red_123", "1","2","3");//向指定key中存放set集合
[java] view plain copy
stringRedisTemplate.expire("red_123",1000 , TimeUnit.MILLISECONDS);//设置过期时间
[java] view plain copy
stringRedisTemplate.opsForSet().isMember("red_123", "1")//根据key查看集合中是否存在指定数据
[java] view plain copy
stringRedisTemplate.opsForSet().members("red_123");//根据key获取set集合  

摘自:《Redis开发与运维》 — 付磊 张益军
在豆瓣阅读书店查看:https://read.douban.com/ebook/30898272/
本作品由华章数媒授权豆瓣阅读全球范围内电子版制作与发行。
© 版权所有,侵权必究。

Redis入门之二6379端口相关推荐

  1. Redis入门(二)安装和基本操作

    1.Window和Linux系统下安装Redis: http://www.cnblogs.com/HoverM/p/9448699.html 2.Redis解压后目录: redis-server:re ...

  2. Redis入门(二)之数据类型

    一.Redis 数据类型 Redis支持五种数据类型: (1)string(字符串) (2)hash(哈希) (3)list(列表) (4)set(集合) (5)zset(sorted set,有序集 ...

  3. redis通过6379端口无法连接服务器(redis-server.exe闪退)

    redis通过6379端口无法连接服务器(redis-server.exe闪退) redis通过6379端口无法连接服务器(redis-server.exe闪退) 程序中报错:Unable to co ...

  4. Redis部署启动多个端口实例

    环境部署Redis时,多个测试环境共用一个redis时,会存在不同的应用使用不同的Redis实例端口,已达到一台redis服务器实现不同环境的调用,互不影响. 故存在了此需求,一个redis启动多个端 ...

  5. Redis入门教程(二)

    推荐阅读: Redis入门教程(一)https://www.cnblogs.com/jichi/p/10285346.html 5. Redis 的数据结构 5.1 Redis 数据结构介绍 redi ...

  6. redis 6379端口telnet不通的解决办法

    1.reids服务器的6379端口telnet不通 2. 查看reids进程和端口,都是存在的.只是ip地址是127.0.0.1而不是0.0.0.0,只是本机能使用 3.查找redis的配置文件red ...

  7. 解决阿里云redis监听6379,配置规则也将6379端口开放,但是外网仍无法连接6379的问题。

    问题描述: 阿里云linux安装完成redis,并且已经运行,检测6379端口,显示redis-server正在监听,如图 查看阿里云端口配置规则,6379端口对外开放 解决方法: 查看阿里云端口开放 ...

  8. [阿里云]Redis的6379端口开通访问所踩到的坑

    阿里云上Redis的6379端口开通访问所踩到的坑 简单记一下踩到的坑: 首先要现在阿里云的控制台开启相应的端口,参考以下文章: (ESC) https://blog.csdn.net/Shenpib ...

  9. 关于redis出现6379端口号异常处理方法

    关于redis出现6379端口号异常处理方法 问题查看: 1.查看端口号是否被占用 netstat -ano 查看全部 netstat -aon | findstr "6379" ...

最新文章

  1. 为Delphi应用增加脚本支持
  2. java二次封装_基于OKhttp+Rxjava2+Retrofit进行二次封装
  3. 2021.11.18
  4. NGINX内部:我们如何设计性能和规模
  5. [转]通达信主图指标--13日黄金K线
  6. 后台管理数据库连接出错,请检查Conn.asp文件中的数据库参数设置的解决办法
  7. 基于RNN实现搜狐新闻数据文本分类
  8. python stack unstack_Python之数据重塑
  9. What Is 'FTW'? What Does It Mean?
  10. rust-crate
  11. linux网络编程相关函数(一)
  12. c#程序设计语言杜松江版_清华大学出版社-图书详情-《C#语言Windows程序设计(第2版)》...
  13. 微信企业号和手机关联的方式
  14. 五年后的深圳是天堂还是地狱?
  15. 7000字,讲透数据指标体系的建设
  16. js添加和删除元素节点
  17. ITU-R 建议书下载网址
  18. 信息论与编码 通信工程 曹瑞珂 P02014263
  19. 我的世界1.12.2java下载_我的世界1.12.2
  20. matlab如何打开flt文件,FIT文件格式解析及MATLAB读取程序

热门文章

  1. 12如何隐藏dock栏_ iOS 13 隐藏 Dock栏,一张神奇壁纸就可以
  2. 服务器红帽操作系统安装,pxe无人值守安装 红帽操作系统
  3. java cl 規格_Java JavaCL類代碼示例
  4. numpy 加速 矩阵相加_Numpy知识
  5. q learning简单理解_班级励志标语格言-生活其实很简单,过了今天就是明天
  6. JDK8的JVM优化实操及部分原理加深理解
  7. SUPERSET使用笔记
  8. ERROR: Minions returned with non-zero exit code
  9. 防止SQL注入和XSS攻击Filter
  10. ”易书网“开发总结——管理篇