用vs2012怎么做网站,上海 网站建设 排名,网站建设的内部风险,建设搜索引擎网站一、字符串对象概述字符串类型是Redis最基础的数据结构。首先键都是字符串类型#xff0c;而且其他几种数据结构都是在字符串类型基础上构建的#xff0c;所以字符串类型能为其他四种数据结构的学习奠定基础字符串就是一个由字节组成的序列如下图所示#xff0c;字符串类型的… 一、字符串对象概述字符串类型是Redis最基础的数据结构。首先键都是字符串类型而且其他几种数据结构都是在字符串类型基础上构建的所以字符串类型能为其他四种数据结构的学习奠定基础字符串就是一个由字节组成的序列如下图所示字符串类型的值实际可以是字符串简单的字符串、复杂的字符串例如JSON、XML数字 整数、浮点数二进制图片、音频、视频但是值最大不能超过512MB二、命令设置值SET、SETEX、SETNXset设置值。参数如下ex seconds为键设置秒级过期时间px milliseconds为键设置毫秒级过期时间nx键必须不存在才可以设置成功用于添加xx与nx相反键必须存在才可以设置成功用于更新set key value [ex seconds] [px milliseconds] [nx|xx]setex、setnx它们的作用和set命令的ex和nx选项是一样的setex设置键的时候同时设置过期时间setnx键必须不存在才可以设置成功否则出错setex key seconds value
setnx key value
setnx和setxx在实际使用中有什么应用场景吗以setnx命令为例子由于 Redis的单线程命令处理机制如果有多个客户端同时执行setnx key value 根据setnx的特性只有一个客户端能设置成功setnx可以作为分布式锁的一种实现方案Redis官方给出了使用setnx实现分布式锁的方法http://redis.io/topics/distlock获取值GETget key如果要获取的键不存在则返回nil空批量设置值MSETmset key value [key value ...]例如下面依次设置4个键值对批量获取值MGET如果有些键不存在那么它的值为nil空mget key [key ...]
例如下面获取键为a、b、c、d、e的值其中e键不存在批量操作的好处批量操作命令可以有效提高开发效率假如没有mget这样的命令要执行n次get命令需要耗时如下n次get时间 n次网络时间 n次命令时间使用mget命令后要执行n次get命令操作只需要耗时n次get时间 1次网络时间 n次命令时间Redis可以支撑每秒数万的读写操作但是这指的是Redis服务端的处理能力对于客户端来说一次命令除了命令时间还是有网络时间假设网络时间为1毫秒命令时间为0.1毫秒按照每秒处理1万条命令算那么执行1000次get命令和1次mget命令的区别如下图所示因为Redis的处理能力已经足够高对于开发人员来说网络可能会成为性能的瓶颈学会使用批量操作有助于提高业务处理效率但是要注意的是每次批 量操作所发送的命令数不是无节制的如果数量过多可能造成Redis阻塞或 者网络拥塞。字符串的自增命令和自减命令命令用例和描述INCRINCR key-name 将键存储的值加上lDECRDECR key-name 将键存储的值减去ⅠINCRBYINCRBY key-name amount 将键存储的值加上整数amountDECRBYDECRBY key-name amount 将键存储的值减去整数amountINCRBYELOAT工NCRBYFLOAT key-name amount 将键存储的值加上浮点数amount这个命令在Redis 2.6或以上的版本可用概念用户可以通过给定一个任意的数值对存储着整数或者浮点数的字符串执行自增increment、自减操作decrement在需要的时候Redis还会将整数转换为浮点数整数的取值范围和系统的长整数long integer的取值范围相同32位系统中就是32位有符号整数64位系统中就是64位有符号整数而浮点数的取值范围和精度则与IEEE 754标准的双精度浮点数double相同返回值INCR返回增加后键的值。返回值分为三种DECR返回删除后键的值INCRBY返回增加后键的值DECRBY返回删除后键的值INCRBYFLOAT返回增加后键的值注意事项如果对一个不存在的键或者一个保存了空串的键执行自增或者自减操作那么Redis在执行操作时会将这个键的值作为0来处理如果所操作的字符串不是一个能被解释为整数或者浮点数的字符串那么这些命令的操作将返回一个错误很多存储系统和编程语言内部使用CAS机制实现计数功能会有一定的CPU开销但在Redis中完全不存在这个问题因为Redis是单线程架构任 何命令到了Redis服务端都要顺序执行演示案例如下 STRLEN获取字符串长度备注中文占3个字节strlen key GETSET设置并返回原值。getset和set一样会设置值但是不同的是它同时会返回键原来的值getset key value下面给出了其他一些演示案例注意SETRANGE的用法下图是字符串类型命令的时间复杂度命令时间复杂度set key valueo(l)get keyo(1)del key [key ...]o(k)k是键的个数mset key value [ key value ...]O(k)t是键的个致mget key [key ...]o()I是键的个致incr keyo1)decr keyo(1)incrby key incremento(1)decrby key decremento(1)incrbyfloat key incremento(1)append key valueo(1)strlen keyo(1)setrange key offset valueo(1)getrange key start endoo)n是宁符串长度由于获取字符串非常快所以如果字符非不是很长可以视阿为O(1)三、内部编码字符串类型的内部编码有3种int8个字节的长整型embstr小于等于39个字节的字符串raw大于39个字节的字符串演示说明Redis会根据当前值的类型和长度决定使用哪种内部编码实现整数类型示例如下短字符串示例如下长字符串示例如下四、典型使用场景①缓存功能下图是比较典型的缓存使用场景其中Redis作为缓存层MySQL作为存储层绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性所以缓存通常能起到加速读写和降低后端压力的作用下面伪代码模拟了上图的访问过程//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;}//3.如果没有从Redis获取到用户信息需要从MySQL中进行获取并将结果回写到Redis添加1小时3600秒过期时间//从MySQL获取用户信息userInfo mysql.get(id);// 将userInfo序列化并存入Redisredis.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;}
应用场景1缓存热门图片set redis-log.jpg redis-log-data应用场景2存储文章。当用户想在博客中撰写一篇新文章的时候程序就需要把文章的标题、内容、作者、发表时间等多 项信息存储起来并在用户阅读文章的时候取出来这些信息。可以使用 mset mget msetnx 命令来进行开发提示与MySQL等关系型数据库不同的是Redis没有命令空间而且也没有对键名有强制要求除了不能使用一些特殊字符但设计合理的键名有利于防止键冲突和项目的可维护性比较推荐的方式是使用“业务名对象 名id[属性]”作为键名也可以不是分号例如MySQL的数据库名为 vs用户表名为user那么对应的键可以用vsuser1vsuser1name来表示如果当前Redis只被一个业务使用甚至可以去掉“vs”。如 果键名比较长例如“user{uid}friendsmessages{mid}”可以在能描 述键含义的前提下适当减少键的长度例如变为“u{uid}frm{mid}”从而减少由于键过长的内存浪费②计数许多应用都会使用Redis作为计数的基础工具它可以实现快速计数、 查询缓存的功能同时数据可以异步落地到其他数据源应用场景1文章长度计数功能、文章摘要、文章计数文章长度STRLEN article:10086:content文章摘要GETRANGE article:10086:content 0 5文章阅读计数INCRBY article:10086:count应用场景2例如笔者所在团队的视频播放数系统就是使用Redis作为视频播放数计数的基础组件用户每播放一次视频相应的视频播放数就会自增1。代码如下所示long incrVideoCounter(long id) {
key video:playCount: id;
return redis.incr(key);
}
开发提示实际上一个真实的计数系统要考虑的问题会很多防作弊、按照不同维度计数数据持久化到底层数据源等③共享Session如下图所示一个分布式Web服务将用户的Session信息例如用户登录信息保存在各自服务器中这样会造成一个问题出于负载均衡的考虑分布式服务会将用户的访问均衡到不同服务器上用户刷新一次访问可能会发现需要重新登录这个问题是用户无法容忍的为了解决这个问题可以使用Redis将用户的Session进行集中管理如下图所示在这种模式下只要保证Redis是高可用和扩展性的每次用户更新或者查询登录信息都直接从Redis中集中获取④限速器应用场景1很多应用出于安全的考虑会在每次进行登录时让用户输入手机验证 码从而确定是否是用户本人。但是为了短信接口不被频繁访问会限制用 户每分钟获取验证码的频率例如一分钟不能超过5次如下图所示此功能可以使用Redis来实现下面的伪代码给出了基本实现思路phoneNum 138xxxxxxxx;key shortMsg:limit: phoneNum;//SET key value EX 60 NXisExists redis.set(key,1,EX 60,NX);if(isExists ! null || redis.incr(key) 5){// 通过}else{// 限速}
应用场景2防止用户的账号遭到暴力破解如果同个账号连续好几次输入错误的密码则限制账号的登录只 能等 30 分钟后再次登录比如设置 3 次1SET max:execute:times 32密码出错时 DECR max:execute:times3当 max:execute:times 的值小于 0 时则禁止登录并可以设置 SETEX login:error:darren 1800 Incorrect password然后使用 TTL login:error:darren 1800 检测对应剩余的时间应用场景3例如一些网站为了防止网页内容被网络爬虫疯狂抓取限制一个IP地址在固定的时间段内能够访问的页面数量.