Redis 应用分析

官网http://redis.io

定义:持久化的高性能key-value内存型数据库

应用场景:数据缓存、聊天系统、访问量统计、消息队列、分布式锁等等

优势对比:

  •轻量级 : redis非常轻量(源码仅1.5M),就个人而言我更喜欢小而轻的东西,对于一些尽量想要完美而庞大的东西来说我是非常反感的,

        有些东西尽可能的追求完美反而忽略了最本质的东西或者说是产品设计的初衷

  •持久化 : redis 提供了非常有好的持久化支持,保证数据完整性

  •高性能 : redis 是基于内存型的中间件,内存型意味着更优秀的性能(实际测试,单机单线程内网环境下可完成10000次/s的写操作),中见间的特性使他对分布式有着很好的支持

  •丰富的数据类型和命令 : redis共有String、List、Hash、Set、SortSet 5种数据类型和丰富的操作命令,这些特性使redis除了基本功能之外,可以应用于多种场景

  •丰富的客户端语言支持

  •使用简单

redis应用之分一  分布式锁实现:

原理:分布式锁主要应用了redis 的 setnx 命令特性,setnx key value,将key的值设为value,当key已存在时则不做处理,我们利用其不能同时赋值的特性实现锁的效果

代码实现:获取锁

 1 /**
 2      * 获取分布式锁 DLock
 3      * @param key 锁标志
 4      * @param holder 锁持有者(一般为uuid,唯一标识当前锁的持有者)
 5      * @param timeout 获取锁的超时时间 毫秒
 6      * @return
 7      */
 8     public static boolean getDLock(String key, String holder, long timeout){
 9         Jedis jedis = DRJedis.getJedisPool();
10         //设置获取锁的超时时间
11         long end = System.currentTimeMillis() + timeout;
12         while (System.currentTimeMillis() < end){
13             if (jedis.setnx(LOCK_PREFIX + key, holder) == 1) return true;
14             try {
15                 Thread.sleep(10);
16             } catch (InterruptedException e) {
17                 log.error("获取 DLock 异常", e);
18                 return false;
19             }
20         }
21         log.error("获取 DLock 超时");
22         return false;
23     }

  这个方法表示如果setnx成功,表示当前没有别的线程持有key这个锁,则获取锁,同时阻止其他线程再次获取这个锁,如果获取所失败,则在timeout时间范围内尝试尝试重新获取,否则返回获取锁失败

释放锁:释放锁即删除key操作,以便于其它的线程可以setnx

 1 /**
 2      * 释放锁
 3      * @param key 锁标志
 4      * @param holder 锁持有者(一般为uuid,唯一标识当前锁的持有者)
 5      */
 6     public static void releaseDLock(String key, String holder){
 7         Jedis jedis = DRJedis.getJedisPool();
 8         while (true){
 9             try {
10                 jedis.watch(LOCK_PREFIX + key);
11                 String value = jedis.get(LOCK_PREFIX + key);
12                 if(value != null && value.equals(holder)){// 保证释放的是当前持有者的锁
13                     Transaction tran = jedis.multi();
14                     jedis.del(LOCK_PREFIX + key);
15                     tran.exec();
16                 }
17                 jedis.unwatch();
18                 break;
19             }catch (Exception e){
20                 log.error("释放锁异常", e);
21                 break;
22             }
23         }
24     }

  这个方法表示释放锁,通过事务保证同时时候放锁操作

redis应用之分二  MQ实现:

原理:mq是基于redis list 列表数据类型的实现,右端入队,左端出队的先入先出特性

生产消息代码

 1 /**
 2      * 生产消息
 3      * @param key 消息key
 4      * @param message 消息体,支持批量生产消息,至少生产一条消息
 5      */
 6     public static void product(String key, String... message){
 7         try{
 8             DRJedis.getJedisPool().rpush(MQ_PREFIX + key, message);
 9         }catch(Exception e){
10             log.error("jedis product message", e);
11         }
12     }

rpush 从右端推入队列

消费消息:

 1 /**
 2      * 消费消息
 3      * @param key 消息key
 4      * @param customer 消息消费业务,需要实现Customer接口的customer方法进行业务处理
 5      */
 6     public static void customer(String key, ICustomer customer){
 7         try{
 8             Jedis jedis = DRJedis.getJedisPool();
 9             while (true){
10                 //弹出消息
11                 List<String> messages = jedis.blpop(0, MQ_PREFIX + key);
12                 if (messages.size() >= 2){
13                     try {
14                         //消费消息
15                         customer.customer(messages.get(0), messages.get(1));
16                     }catch (RollbackException e){
17                         //消息消费失败则要重新生产消息,并有左侧压入队列,保证下次第一个被消费
18                         jedis.lpush(messages.get(0), messages.get(1));
19                     }
20                 }
21             }
22         }catch(Exception e){
23             log.error("jedis customer message", e);
24         }
25     }

blpop 从左端弹出消息,如果队列为空则阻塞消息等待,此方法使用了while(true)无限循环的方式模拟监听器,以便于及时的消费消息,ICustomer 定义具体的消费业务,并抛出RollbackException异常表示,消息消费失败,需要回滚,则重新从左端推入队列,保证下次被第一个消费

1 /**
2  * Created by xiao on 2016/5/20.
3 */
4 public interface ICustomer {
5
6     void customer(String key, String message) throws RollbackException;
7
8 }

消费消息的业务需要实现ICustomer的customer方法,消费消息

 1 /**
 2  * 回滚异常
 3  */
 4 public class RollbackException extends Exception {
 5
 6     public RollbackException(String message) {
 7         super(message);
 8     }
 9
10     public RollbackException() {
11         super();
12     }
13
14     public RollbackException(String message, Throwable cause) {
15         super(message, cause);
16     }
17
18     public RollbackException(Throwable cause) {
19         super(cause);
20     }
21
22     protected RollbackException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
23         super(message, cause, enableSuppression, writableStackTrace);
24     }
25 }

时间: 2024-10-08 10:34:39

Redis 应用分析的相关文章

[转]Redis实现分析

Redis实现分析 浏览次数:1018次 KITERUNNER_T 2014年10月19日 字号: 大 中 小 分享到: QQ空间 新浪微博 腾讯微博 人人网 豆瓣网 开心网 更多 1 1 环境准备 从2.6.4版本为基础了解redis的设计与实现,首先搭建一个原始模型,以便根据这个模型分析其代码的设计与实现(当然,随着进一步对 redis细节的了解,肯定会对该模型进行调整,以便更适合分析其设计与实现细节).在对该版本有较深的了解后,跟随github代码库,追踪新功能添 加.bug/issue等

redis内存分析

redis内存分析和清理 web项目中经常会使用redis作为缓存,当项目了运行一段时间后,由于不恰当的使用方法和需求迭代频繁,导致redis内存快速增长,这时就需要对redis的key进行分析,删掉无用的key以节省空间 使用redis自带的命令查看 使用redis自带的info keyspace命令可以查看简略的key分布情况 使用rdbtools工具分析 rdbtools是用python开发的第三方工具,主要作用有: 1.生成csv分析报告 rdb -c memory dump.rdb >

redis启动分析

http://ordinary.iteye.com/blog/1097457 从本篇文章开始(命名为Redis分析系列),将会通过分析Redis的源代码(以Redis 2.2.0 RC1为准),来对它的内部实现做一些探讨.本文主要介绍Redis启动加载过程,总体上可以分为如下几步: 1. 初始化全局服务器配置 2. 加载配置文件(如果指定了配置文件,否则使用默认配置) 3. 初始化服务器 4. 加载数据库 5. 网络监听 整个启动加载过程如下图所示: 下面对于上图中的各个步骤一些介绍,有些部分(

Elasticsearch+Logstash+Kinaba+Redis日志分析系统

一.简介 1.组成 ELK由Elasticsearch.Logstash和Kibana三部分组件组成: Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等. Logstash是一个完全开源的工具,它可以对你的日志进行收集.分析,并将其存储供以后使用 kibana 是一个开源和免费的工具,它可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可

Redis 数据类型分析 字符串 哈希 列表 集合 有序集合 优缺点 分析 注意事项 存储结构

一.提高Redis使用性能秘诀 KEY尽量少的原则,能放在1个KEY的就放入1个KEY,KEY开销很大尽量减少与Redis发生的交互次数,能批量的就批量,能事务.管道的就事务.管道从业务架构分析确定使用哪种数据类型,从全局出发,如果类型选错了再改变就很不容易使用每一个Redis命令注意是O(1),还是O(N),切记滥用,认准每个命令的特性再使用也不迟使用PHP Redis的C语言扩展,性能远远高于PHP脚本编写的文件时刻清醒你往Redis里存储了什么,频繁交互.相对静态的小数据存储至Redis是

Redis源代码分析(二十八)--- object创建和释放redisObject物

今天的学习更有效率.该Rio分析过,学习之间的另一种方式RedisObject文件,只想说RedisObject有些生成和转换.都是很类似的.列出里面长长的API列表: /* ------------ API --------------------- */ robj *createObject(int type, void *ptr) /* 最初的创建robj对象方法,后面的创建方法与此相似 */ robj *createStringObject(char *ptr, size_t len)

Redis源代码分析(八)--- t_hash哈希转换

在上次的zipmap分析完之后,事实上关于redis源码结构体部分的内容事实上已经所有结束了.由于以下还有几个和结构体相关的操作类,就页把他们归并到struct包下了.这类的文件有:t_hash.c,z_list,z_set.c,t_string.c,t_zset.c,这些文件的功能事实上都差点儿相同,就是用来实现Client和Server之间的命令处理的操作类,通过robj的形式,把dict,ziplist等存入robj中,进行各个转换.实现命令操作.避开了结构体原先的复杂结构,相当于是封装了

Redis源代码分析(五)--- sparkline微线图

sparkline这个单词,我第一次看的时候.也不知道这什么意思啊,曾经根本没听过啊,可是这真真实实的出如今了redis的代码中了,刚刚開始以为这也是属于普通的队列嘛.就把他分在了struct包里了. 好来分析完了.与原本我所想的差太大了.sparkline英文中的意思"微线图",这么说吧.类似于折线图,由一个一个信息点构成.所以看到这个意思.你也许就明确了sparkline.c是干什么用的了吧,就是绘图用的. 我们看看这个绘图的内部结构是什么,绘图须要的元素是哪些: /* spark

redis 源代码分析(一) 内存管理

一,redis内存管理介绍 redis是一个基于内存的key-value的数据库,其内存管理是很重要的,为了屏蔽不同平台之间的差异,以及统计内存占用量等,redis对内存分配函数进行了一层封装,程序中统一使用zmalloc,zfree一系列函数,其相应的源代码在src/zmalloc.h和src/zmalloc.c两个文件里,源代码点这里. 二,redis内存管理源代码分析 redis封装是为了屏蔽底层平台的差异,同一时候方便自己实现相关的函数,我们能够通过src/zmalloc.h 文件里的相

Redis源代码分析(二十四)--- tool工具类(2)

在上篇文章中初步的分析了一下,Redis工具类文件里的一些使用方法,包含2个随机算法和循环冗余校验算法,今天,继续学习Redis中的其它的一些辅助工具类的使用方法.包含里面的大小端转换算法,sha算法在Redis中的实现和通用工具类算法util.c. 先来看看大小端转换算法,大小端学习过操作系统的人一定知道是什么意思,在不同的操作系统中,高位数字的存储方式存在,高位在前,低位在后,或是高位在后,低位在前,所以这里面就涉及到转换,依据不同的操作系统,有不同的转换方式,所以Redis在这方面就开放了