redis分布式锁

Redis:Redis的概念及各项功能

时光怂恿深爱的人放手 提交于 2019-11-30 05:45:11
Redis:简述Redis 的概念及各项功能 一、Redis简介 官方简介:Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统,你可以把它作为数据库,缓存和消息中间件来使用。 同时支持strings,lists,hashes,sets,sorted sets,bitmaps,hyperloglogs和geospatial indexes等数据类型。 它还内建了复制,lua脚本,LRU,事务等功能,通过redis sentinel实现高可用,通过redis cluster实现了自动分片。以及事务,发布/订阅,自动故障转移等等。 综上所述,Redis提供了丰富的功能,这些功能都是干嘛用的?都解决了什么问题?什么情况下才会用到相应的功能?那么下面来粗略的解释下。 二、面临的需求(问题)及解决方案 需求(问题) :我们有一个提供热点新闻列表的api接口,api的消费者抱怨说每次请求都要2秒左右才能返回结果。随后我们就着手于如何提升一下api消费者感知的性能。 基于HTTP的缓存控制 很快最简单粗暴的第一个方案就出来了:为API的响应加上基于HTTP的缓存控制 cache-control:max-age=600 ,即让消费者可以缓存这个响应十分钟。如果api消费者如果有效的利用了响应中的缓存控制信息,则可以有效的改善其感知的性能(10分钟以内)。

阿里面试题,看完直接转行

若如初见. 提交于 2019-11-30 04:23:43
文章目录 JAVA基础 JVM知识 开源框架知识 操作系统 多线程 TCP与HTTP 架构设计与分布式 算法 数据库知识 消息队列 缓存 搜索 JAVA基础 JAVA中的几种基本数据类型是什么,各自占用多少字节。 String类能被继承吗,为什么。 String,Stringbuffer,StringBuilder的区别。 ArrayList和LinkedList有什么区别。 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字 段,当new的时候,他们的执行顺序。 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们 内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。 JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何 设计。 有没有有顺序的Map实现类,如果有,他们是怎么保证有序的。 抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口 么。 继承和聚合的区别在哪。 IO模型有哪些,讲讲你理解的nio ,他和bio,aio的区别是啥,谈谈reactor模型。 反射的原理,反射创建类实例的三种方式是什么。 反射中,Class.forName和ClassLoader区别 。 描述动态代理的几种实现方式

《即时消息技术剖析与实战》学习笔记7——IM系统的消息未读

半世苍凉 提交于 2019-11-30 03:38:32
一、什么是消息未读 消息未读包括 会话未读 和 总未读 。前者指的是当前用户和某一聊天方的未读消息数,后者指的是当前用户的所有未读消息数,也就是所有会话未读的和。比如用户A收到用户B的2条消息,还收到用户C的3条消息,则用户A与B的会话未读数是2,用户A与C的会话未读数是3,用户A的总未读是5。 二、消息未读的维护 会话未读和总未读数一般都是单独维护的。这是因为: 1)总未读的使用场景较多,会被高频使用。如APP角标未读展示; 2)如果不单独维护,则总未读数需要通过计算所有的会话未读数,一旦会话数较多,就需要多次读取存储,多次获取累加的操作容易出现性能瓶颈。而且一旦发生超时等意外,就会无法获取到会话未读数,导致总未读数不准确。 三、消息未读的一致性 单独维护总未读和会话未读数会带来新问题,也就是消息总未读数与(多个)会话未读数不一致的问题。比如APP角标显示5,表示有5条未读消息,但用户点进去却发现没有新消息或只有3条消息,就会给用户造成不好的体验。 消息未读不一致的原因 用户B的初始状态:会话未读数和总未读数都是0。 用户A给用户B发消息,消息到达IM服务后,执行加未读操作:先把用户B与用户A的会话未读数加1,再把用户B的总未读数加1,然后消息推送给用户B。 case1 :假设加会话未读数的操作成功、加总未读数的操作失败了,则用户B的最新状态是:会话未读数是1,总未读数是0。

项目常见面试问题

亡梦爱人 提交于 2019-11-30 02:10:35
项目常见面试问题 阅读目录 项目常见面试问题 回到目录 项目常见面试问题 一、你的项目中缓存粒度是如何选择的? 缓存粒度一共分为4种. 1.缓存某个数值:一个键只保存一个值,性价比较低,使用率低,如果存储的话我们使用redis的String 2.缓存数据对象:数据库记录对应的具体数据,优点是可以多次复用,String,hash 3.缓存数据集合:数据库查询对应的结果集,可以和数据对象配合使用,方便数据对象的重用,hash,list,set,zset,String(zset,String) 4.缓存试图响应:试图返回的相应数据,复用性比较差,String 所以我们项目中主要对数据集合+数据对象进行缓存,他们的优点是复用性强,节省内存空间. 二、使用过redis的那些格式做过缓存,其他应用场景和优缺点是什么? 包括list,zset,set,hash和json字符串 其中我们使用过json字符串和zset set用来存放无序去重的数据, 如果有判断是否存在的需求 zset有排序的需要list,如果说是按时间查询, 查询的结果固定, 不需要分页的情况下,我们使用list因为查询的比较快 但如果有额外排序要求, 而且需要分页, 我们使用zset(查询时间跟查询的长度和数据量有关,跟查询区别无关, 查询速度比较均衡), 增加数据效率和存储的数据量负相关,数据量越大,添加时间越长

三、Redis执行Lua脚本

徘徊边缘 提交于 2019-11-30 01:09:33
前言:   前面我们已经分析了如何实现分布式锁,以及在实现的过程中分布式锁存在的各种问题,并且提出了解决办法,虽然我们上面看似实现了分布式锁,但是却存在一个致命问题,原子性问题,无论是获取锁还是释放锁,都是用多行Redis命令来实现,如果无法保证这个命令执行的原子性,则整个过程中就存在安全问题,在这里我们要引入另一门语言Lua,Lua脚本语言则可以用来解决多行Redis命令原子性问题,下面来看一下Lua脚本语言; 一、Redis中如何执行Lua脚本:    1.EVAL命令:          执行一个脚本包括参数:       script:脚本内容或者脚本地址;       numkeys:脚本中用到的key的数量,接下来的numkeys个数会作为key的参数,剩下的作为arg的参数;       arg:其他参数,会被存入脚本环境中的ARGV数组中,角标从1开始;     示例: EVAL "return 'hello world'" 0 ,其中        "return 'hello world'" :就是脚本的内容,在这里这几返回一个字符串;        0 :也就是说没有用到key参数,直接返回     效果:           2、SCRIPT LOAD命令:          将一个脚本编译并且缓存起来,生成一个SHA1值并且返回,为了方便使用

Redis常见面试题

做~自己de王妃 提交于 2019-11-29 23:26:55
redis介绍   Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API的非关系型数据库。 传统数据库遵循 ACID 规则。而 Nosql(Not Only SQL 的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称) 一般为分布式而分布式一般遵循 CAP 定理。 Github 源码:https://github.com/antirez/redis Redis 官网:https://redis.io/ Redis支持的数据类型? String字符串: 格式: set key value string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。 string类型是Redis最基本的数据类型,一个键最大能存储512MB。 Hash(哈希) 格式: hmset name key1 value1 key2 value2 Redis hash 是一个键值(key=>value)对集合。 Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。 List(列表) Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边

Netty游戏服务器实战开发(8):利用redis或者zookeeper实现3pc分布式事务锁(二)。支撑腾讯系列某手游百万级流量公测

≡放荡痞女 提交于 2019-11-29 23:03:22
导读:在上篇文章中介绍了分布式事务项目的基本原理和工程组件,我们了解到了分布式事务的理论知识。处于实战的经验,我们将理论知识使用到实际项目中。所以我们将借助idea中maven工程 来实战我们的项目。 回到正文: 在上篇文章中我们已经把需要的准备工作做好了。现在我们需要将如何实现分布式3PC事务提交锁。 先睹为快 首先我们先来体验一下事务提交锁的过程,在本项目中我们将在Windows环境下搭建redis环境和zookeeper环境。下面就是我们只需一段分布式加锁程序的过程。一段执行锁发生异常的行为: 定义事物锁的类型: 我们使用分布式事务锁的时候我们需要提供如下几种类型的锁: 1:写锁,WRITE 2:读锁,READ 3:独占写锁,到时间释放:WRITE_TIME 4:强制时间锁,无论获取锁成功,强制时间锁, 到时间时间释放,FORCE_WRITE_TIME 更具上面分析我们将定义一个枚举类来枚举上面所需要的锁。NettyTransactionLockType.java package com.twjitm.transaction.transaction.enums; /** * 事物锁类型 * * @author twjitm- [Created on 2018-08-27 11:50] * @jdk java version "1.8.0_77" */ public enum

Redis 的并发竞争问题是什么?

大城市里の小女人 提交于 2019-11-29 19:34:57
面试题 Redis 的并发竞争问题是什么?如何解决这个问题?了解 Redis 事务的 CAS 方案吗? 面试官心理分析 这个也是线上非常常见的一个问题,就是多客户端同时并发写一个 key,可能本来应该先到的数据后到了,导致数据版本错了;或者是多客户端同时获取一个 key,修改值之后再写回去,只要顺序错了,数据就错了。 而且 redis 自己就有天然解决这个问题的 CAS 类的乐观锁方案。 面试题剖析 某个时刻,多个系统实例都去更新某个 key。可以基于 zookeeper 实现分布式锁。每个系统通过 zookeeper 获取分布式锁,确保同一时间,只能有一个系统实例在操作某个 key,别人都不允许读和写。 你要写入缓存的数据,都是从 mysql 里查出来的,都得写入 mysql 中,写入 mysql 中的时候必须保存一个时间戳,从 mysql 查出来的时候,时间戳也查出来。 每次要写之前,先判断一下当前这个 value 的时间戳是否比缓存里的 value 的时间戳要新。如果是的话,那么可以写,否则,就不能用旧的数据覆盖新的数据。 来源: https://blog.csdn.net/weixin_41688792/article/details/100901063

redis高级

你。 提交于 2019-11-29 19:01:59
一.Redis简介 Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。 Redis是 NoSQL技术阵营中的一员,它通过多种键值数据类型来适应不同场景下的存储需求,借助一些高层级的接口使用其可以胜任,如缓存、队列系统的不同角色 二.Redis特性 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 Redis支持数据的备份,即master-slave模式的数据备份。 三.Redis 优势 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。 丰富的特性 –

Redission

纵然是瞬间 提交于 2019-11-29 18:57:11
Redission 1、原理 2、源码中加锁lua代码 if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]); 分析: 1、为什么要使用lua语言 因为一大堆复杂的业务逻辑,可以通过封装在lua脚本中发送给redis,保证这段复杂业务逻辑执行的原子性 2、lua字段解释 KEYS[1]:表示你加锁的那个key,比如说 RLock lock = redisson.getLock(“myLock”); 这里你自己设置了加锁的那个锁key就是“myLock”。 ARGV[1]:表示锁的有效期,默认30s ARGV[2]:表示表示加锁的客户端ID,类似于下面这样: 8743c9c0