Redis的使用难吗?不难,Redis用好容易吗?不容易。Redis的使用虽然不难,但与业务结合的应用场景特别多、特别紧,用好并不容易。我们希望通过一篇文章及Demo,即可轻松、快速入门并学会应用。

一、Redis 简介

Redis是一个开源的Key-Value存储,但又不仅仅是Key-Value存储,用官网上的话来说,Redis是一个数据结构存储,可用作数据库、缓存和消息中间件。相对于传统的Key-Value存储Memcached来说,Redis具有如下特点:

  • 速度快
  • 丰富的数据结构,除String之外,还有List、Hash、Set、Sorted Set
  • 单线程,避免了线程切换和锁的性能消耗
  • 原子操作
  • 可持久化(RDB与AOF)
  • 发布/订阅
  • 支持Lua脚本
  • 分布式锁
  • 事务
  • 主从复制与高可用(Redis Sentinel)
  • 集群(3.0版本以上)

二、Redis 数据结构

1、String

这是最简单的Redis类型。如果只使用这种类型,Redis就像一个可持久化的Memcached服务器。

2、List

Redis的List是基于双向链表实现的,可以支持反向查找和遍历。

常用案例:聊天系统、社交网络中获取用户最新发表的帖子、简单的消息队列、新闻的分页列表、博客的评论系统。

3、Hash

Hash是一个String类型的field和value之间的映射表,请见下图,类似于.NET中的Hashtable和Dictionary。主要用来存储对象,可以避免序列化的开销和并发修改控制的问题。

4、Set

Set也是一个列表,不过它的特殊之处在于它是可以自动排重的:当需要存储一个列表数据,而又不希望出现重复的时候,Set是一个很好的选择(比如ID的集合)。并且Set提供了判断某个成员是否在一个Set集合内的接口,这也是List所没有的。

5、Sorted Set

Sorted Set和Set的使用场景类似,区别是Sorted Set会根据提供的score参数来进行自动排序。当你需要一个有序的并且不重复的集合列表,那么就可以选择Sorted Set数据结构。常用案例:游戏中的排行榜。

三、 Redis 重要特性

以下特性请重点看管道和事务。

1、管道

Redis管道是指客户端可以将多个命令一次性发送到服务器,然后由服务器一次性返回所有结果。管道技术在批量执行命令的时候可以大大减少网络传输的开销,提高性能。

2、事务

Redis事务是一组命令的集合。一个事务中的命令要么都执行,要么都不执行。如果命令在运行期间出现错误,不会自动回滚。

管道与事务的区别:管道主要是网络上的优化,客户端缓冲一组命令,一次性发送到服务器端执行,但是并不能保证命令是在同一个事务里面执行;而事务是原子性的,可以确保命令执行的时候不会有来自其他客户端的命令插入到命令序列中。

3、分布式锁

分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作,如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。

4、地理信息

从Redis 3.2版本开始,新增了地理信息相关的命令,可以将用户给定的地理位置信息(经纬度)存储起来,并对这些信息进行操作。

四、 使用方法

步骤1、在需要使用Redis的项目中引用FxCommon.dll和Redis.dll

步骤2、在App.config或Web.config文件中添加如下配置

<add key="RedisServerIP" value="redis:uuid845tylabc123@139.198.13.12:4125"/>
<!-- 提供的 Redis 环境是单机版配置。如果 Redis 是主从配置,则还需设置 RedisSlaveServerIP-->
<!--<add key="RedisSlaveServerIP" value="redis:uuid845tylabc123@139.198.13.13:4125"/>--> <!--Redis 数据库。如果不需要指定 Redis 数据库,就配置默认值 0-->
<add key="RedisDefaultDb" value="0"/>

步骤 3、使用 PooledRedisClientManager 类创建 Redis 连接池:

// 读取 Redis 主机 IP 配置信息
string[] redisMasterHosts = ConfigurationManager.ConnectionStrings["RedisServerIP"].ConnectionString.Split(','); // 如果 Redis 服务器是主从配置,那么还需要读取 Redis Slave 机的 IP 配置信息
string[] redisSlaveHosts = null;
var slaveConnection = ConfigurationManager.ConnectionStrings["RedisSlaveServerIP"];
if (slaveConnection != null && !string.IsNullOrWhiteSpace(slaveConnection.ConnectionString))
{
string redisSlaveHostConfig = slaveConnection.ConnectionString;
redisSlaveHosts = redisSlaveHostConfig.Split(',');
} // 读取 RedisDefaultDb 配置
int defaultDb = 0;
string defaultDbSetting = ConfigurationManager.AppSettings["RedisDefaultDb"];
if (!string.IsNullOrWhiteSpace(defaultDbSetting))
{
int.TryParse(defaultDbSetting, out defaultDb);
} var redisClientManagerConfig = new RedisClientManagerConfig
{
MaxReadPoolSize = 50,
MaxWritePoolSize = 50,
DefaultDb = defaultDb
}; // 创建 Redis 连接池
Manager = new PooledRedisClientManager(redisMasterHosts, redisSlaveHosts, redisClientManagerConfig)
{
PoolTimeout = 2000,
ConnectTimeout = 500
};

步骤4、通过PooledRedisClientManager的实例获取Redis客户端,然后就可以开始通过Redis客户端的API进行操作。

五、其它

5.1、 Redis Key命名规范

Redis Key命名规范:AppID:KeyName。

可能有很多人习惯用英文状态的点号来作为AppID和KeyName的分隔符,而笔者建议使用冒号作为AppID和KeyName的分隔符,其原因是:这么写会使Redis Key会以AppID作为分类显示在Redis Desktop Manager中,方便你能够快速查到要查阅的Redis Key对应的Redis Value值,请见下图:

aaarticlea/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==" alt="" />

但如果使用英文状态的点号来作为分隔符的话,那么在Redis Desktop Manager中,Redis Key就不会被分类了,请见下图:

aaarticlea/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==" alt="" />

5.2、常见应用问题

  • 缓存穿透处理:什么是缓存穿透?当根据Redis key在缓存中查询后,不存在对应Value,就应该会在后端系统如DB中去查找,该Key的并发请求量一旦变大,那么就会对DB造成很大的压力。解决办法有:a.前端风险控制,将恶意穿透情况排除在外;b.对查询结果为空的情况依然进行缓存,但缓存时间会设置得很短,一般是几分钟。
  • 缓存雪崩处理:什么是缓存雪崩?当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。解决办法有:后端连接数限制,错误阈值限制,超时处理,缓存失效时间均匀分布,前端永不失效及后端主动更新。
  • 缓存时长:策略定位复杂,需要多维度的计算。
  • 缓存失效:按时失效,事件失效,后端主动更新。
  • 缓存Key:Hash、规则、前缀+Hash,异常情况可人工干预。
  • Lua脚本:服务端批量处理及事务能力,有条件逻辑的可扩展脚本。使用它的好处有:减少网络开销、原子操作、可复用。
  • Limit:可滑动时间窗口,如应用于Session,Memcached需每次传Key和Value。

六、Demo 下载及更多资料

本系列文章涉及内容清单如下,其中有感兴趣的,欢迎关注:

作者介绍

张辉清,10 多年的 IT 老兵,先后担任携程架构师、古大集团首席架构、中青易游 CTO 等职务,主导过两家公司的技术架构升级改造工作。现关注架构与工程效率,技术与业务的匹配与融合,技术价值与创新。

杨丽,拥有多年互联网应用系统研发经验,曾就职于古大集团,现任职中青易游的系统架构师,主要负责公司研发中心业务系统的架构设计以及新技术积累和培训。现阶段主要关注开源软件、软件架构、微服务以及大数据

转载:http://www.infoq.com/cn/articles/architecture-practice-01-redis?utm_source=infoq&utm_campaign=user_page&utm_medium=link

中小型研发团队架构实践:Redis快速入门及应用的更多相关文章

  1. 中小型研发团队架构实践:分布式协调服务ZooKeeper

    一.ZooKeeper 是什么 Apache ZooKeeper 由 Apache Hadoop 的子项目发展而来,于 2010 年 11 月正式成为了 Apache 的顶级项目. 相关厂商内容 优秀 ...

  2. 中小型研发团队架构实践:任务调度Job

    一.Job 简介 Job 类似于数据库中的作业,多用于实现定时执行任务.适用场景主要包括定时轮询数据库同步.定时处理数据.定时邮件通知等. 我们的 Job 分为操作系统级别定时任务 WinJob 和 ...

  3. 中小型研发团队架构实践五:Redis快速入门及应用

    Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...

  4. 中小型研发团队架构实践六:如何用好消息队列RabbitMQ?

    一.写在前面 使用过分布式中间件的人都知道,程序员使用起来并不复杂,常用的客户端 API 就那么几个,比我们日常编写程序时用到的 API 要少得多.但是分布式中间件在中小研发团队中使用得并不多,为什么 ...

  5. 中小型研发团队架构实践八:分布式协调服务ZooKeeper

    一.ZooKeeper 是什么 Apache ZooKeeper 由 Apache Hadoop 的子项目发展而来,于 2010 年 11 月正式成为了 Apache 的顶级项目. ZooKeeper ...

  6. 中小型研发团队架构实践七:集中式日志ELK

    一.集中式日志 日志可分为系统日志.应用日志以及业务日志,系统日志给运维人员使用,应用日志给研发人员使用,业务日志给业务操作人员使用.我们这里主要讲解应用日志,通过应用日志来了解应用的信息和状态,以及 ...

  7. 中小型研发团队架构实践三:微服务架构(MSA)

    一.MSA 简介 1.1.MSA 是什么 微服务架构 MSA 是 Microservice Architect 的简称,它是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相通讯.互相 ...

  8. 中小型研发团队架构实践九:任务调度Job

    一.Job 简介 Job 类似于数据库中的作业,多用于实现定时执行任务.适用场景主要包括定时轮询数据库同步.定时处理数据.定时邮件通知等. 我们的 Job 分为操作系统级别定时任务 WinJob 和 ...

  9. 中小研发团队架构实践之RabbitMQ快速入门及应用

    原文:中小研发团队架构实践之RabbitMQ快速入门及应用 使用过分布式中间件的人都知道,程序员使用起来并不复杂,常用的客户端API就那么几个,比我们日常编写程序时用到的API要少得多.但是分布式中间 ...

随机推荐

  1. 获取asp.net mvc应用程序的根目录

    如果使用Server.MapPath(“controllerName”)这样取得的是带控制权名称的目录, 所以要取得上一级目标,如:Server.MapPath("../"),这才 ...

  2. mysql-mmm故障整理

    Auth: JinDate: 20140414 1.master-slave同步问题1)故障描述和错误代码:监控报警slave故障登录slave服务器查看mysql> show slave st ...

  3. 我告诉你MSDN

    https://msdn.itellyou.cn/ 微软的软件,系统,官方下载

  4. mq组件介绍

    作者:Jaskey Lam链接:https://zhuanlan.zhihu.com/p/25069846来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. RocketM ...

  5. [转]How to solve SSIS error code 0xC020801C/0xC004700C/0xC0047017

    本文转自:http://www.codeproject.com/Articles/534651/HowplustoplussolveplusSSISpluserrorpluscodeplus0xC B ...

  6. android 启动socket 失败:socket(af_inet sock_stream 0) 返回-1

    Android 启动socket 失败:socket(af_inet sock_stream 0) 返回-1 原因权限问题, 应该添加如下权限: <uses-permission android ...

  7. 关于Django迁移出现问题

    关于Django迁移出现问题 源码: #coding:utf- from django.db import models # Create your models here. class BookIn ...

  8. jquery获取li里面的第一个a标签

    $("li").children("a:eq(0)") ; children()查找子元素,eq() 查找第几个 $('.active').children(& ...

  9. java中return的作用

    脑补一下基础的东西,return的用法. return的常用作用有以下两种第一种用法是返回参数所用的关键字,假如一个有返回值的方法执行完了之后需要返回一个参数,示例: public string fu ...

  10. 【架构】Twitter高性能RPC框架Finagle介绍

    Twitter的RPC框架Finagle简介 Finagle是Twitter基于Netty开发的支持容错的.协议无关的RPC框架,该框架支撑了Twitter的核心服务.来自Twitter的软件工程师J ...