分布式锁

Zookeeper实现的分布式锁

半腔热情 提交于 2020-03-08 06:39:31
Zookeeper实现的分布式锁 zookeeper是一个分布式协调中间件,既可以用来做分布式的id还可以用来做配置中心、还有我们接下来要说的分布式锁。 在说分布式锁之前要先介绍一下zookeeper,它是树形结构,每个节点都可以存储值和创建子节点。而zookeeper的节点一共分为四种分别是临时节点,持久化节点,临时有序节点,持久化有序节点。 Zookeeper节点类型 临时节点 顾名思义,临时的节点,有个需要注意的是当客户端与服务端的会话关闭的时候,临时节点就会被自动删除掉 持久化节点 这个跟临时节点的区别就是,就算会话关闭,节点也不会被关闭。 临时有序节点 这个跟临时节点唯一的区别就是,创建的节点是有序的例如上一个节点创建为 /00000000001 ,那下一个节点就是 /00000000002 ,依次递增 持久化有序节点 这个跟临时有序节点的区别也是会话就算关闭,创建的节点也不会被删除掉 分布式锁的实现原理 多个节点需要共享一个数据或文件,节点之间同时竞争获取执行权限,当其中某个节点获取到执行权限以后,另一个就必须等待占有执行权限的执行完成并将执行权限释放出来,只要能满足条件互斥就能实现分布式锁,比如数据库的锁表,唯一索引,Redis的 setnx 函数,还有我们刚才讲的zookeeper的临时有序节点的。 临时节点如何创建分布式锁 我们先看个图,然后根据下面这个图来讲

使用Redis单实例实现分布式锁

自古美人都是妖i 提交于 2020-03-08 06:33:59
为什么使用redis分布式锁 在同一个jvm进程中时,可以使用JUC提供的一些锁来解决多个线程竞争同一个共享资源时候的线程安全问题,但是当多个不同机器上的不同jvm进程共同竞争同一个共享资源时候,juc包的锁就无能无力了,这时候就需要分布式锁了。常见的有使用zk的最小版本,redis的set函数,数据库锁来实现。 使用分布式锁 package com.jiaduo.DistributedLock; import java.util.Collections; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class DistributedLock { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; private static final Long RELEASE_SUCCESS = 1L; private static void validParam(JedisPool jedisPool, String

jedis实现分布式锁

自作多情 提交于 2020-03-07 14:15:00
jedis分布式锁实现的4个要点 1.互斥性。在任意时刻,只有一个客户端能持有锁。 2.不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。 3.具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。 4.解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。 代码的实现 //加锁 public class RedisTool { private static final String LOCK_SUCCESS = "OK" ; private static final String SET_IF_NOT_EXIST = "NX" ; private static final String SET_WITH_EXPIRE_TIME = "PX" ; /** * 尝试获取分布式锁 * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @param expireTime 超期时间 * @return 是否获取成功 */ public static boolean tryGetDistributedLock ( Jedis jedis , String lockKey , String requestId , int

redis常见应用场景

♀尐吖头ヾ 提交于 2020-03-06 15:39:26
1、热点数据的缓存 由于redis访问速度块、支持的数据类型比较丰富,所以redis很适合用来存储热点数据,另外结合expire,我们可以设置过期时间然后再进行缓存更新操作,这个功能最为常见,我们几乎所有的项目都有所运用。 2、限时业务的运用 redis中可以使用expire命令设置一个键的生存时间,到时间后redis会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。 3、计数器相关问题 redis由于incrby命令可以实现原子性的递增,所以可以运用于高并发的秒杀活动、分布式序列号的生成、具体业务还体现在比如限制一个手机号发多少条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。 4、排行榜相关问题 关系型数据库在排行榜方面查询速度普遍偏慢,所以可以借助redis的SortedSet进行热点数据的排序。 在奶茶活动中,我们需要展示各个部门的点赞排行榜, 所以我针对每个部门做了一个SortedSet,然后以用户的openid作为上面的username,以用户的点赞数作为上面的score, 然后针对每个用户做一个hash,通过zrangebyscore就可以按照点赞数获取排行榜,然后再根据username获取用户的hash信息,这个当时在实际运用中性能体验也蛮不错的。 5、分布式锁 这个主要利用redis的setnx命令进行,setnx:

收藏慢慢看系列:简洁实用的Redis分布式锁用法

烈酒焚心 提交于 2020-03-06 10:19:41
在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2.x以上版本中使用Redis时,其客户端库已经默认使用lettuce。 所以本文将直接介绍在Spring Boot2.x以上项目中快速使用Redis分布式锁的功能的方法,希望能够更新你的知识库! Redis分布式锁原理概述 实际上Redis服务本身并不提供分布式锁这样的机制,但是作为全局Key-Value存储系统,客户端可以利用Redis提供的基本功能并通过一定的算法设计来实现分布式锁功能。目前已有不少博客文章及代码库描述了如何使用Redis来实现分布式锁,但是许多实现相对比较简单,安全性也比较低。在Redis的官方文档中推荐了一种叫做RedLock的算法来实现基于Redis的分布式锁功能,现阶段已存在基于该算法的多种语言版本的Redis客户端实现库。其中Java领域最为知名的是Redisson库。但由于Redisson不仅实现了分布式锁功能,还额外实现了一套Redis分布式数据结构,因此会显得比较重,加上最新的基于Spring Boot.2.x以上版本使用Redis时,其客户端库已经默认使用了lettuce(比Redisson、Jedis线程更安全、更轻量级的一种Java

redis分布式锁的实现

爱⌒轻易说出口 提交于 2020-03-06 01:41:01
为什么要用分布式锁 使用场景 xx游戏平台举办了一个回馈用户活动,只要等级达到x等级,即可领取xx装备。可能有些人,有过这样的想,是不是,只要我速度够快,就能领到多份奖品啊,想想都美滋滋。结果,系统显示, 当前操作过于频繁,请稍后再试 。what??? 这个的话,就涉及到了锁。同个账号,当我们的第一次请求到服务器的时候,已经被加上了锁,当还没释放锁的时候,再次请求,则不能拿到锁,只能继续等待。(当然这种场景不一定要用分布式锁进行实现,比如数据库的索引唯一性也可实行,只是举个例子) 说到锁的话,则要从公司系统的架构说起了。一开始,很多公司的系统不是很庞大,为了节省资源,单机即可满足需求。对于这种单机模式的系统,我们可以用java原生的synchronized和lock这两种锁,只要锁住相应的类、对象或者方法等即可简单的时间锁机制。 但随着公司的不断发展,用户量的增加,需要对业务进行拆分。这个时候,微服务就出现了,服务拆分了,同时为了保证高可用,每个服务会根据负载等因素,选择部署不同数量的机器,进行集群管理。 在分布式系统的话,则出现了同个服务,部署在不同的机器上。因为我们上面采用的是基于JVM的锁机制,没法保证同个用户请求的锁都是同个JVM(其实可以通过设置负载均衡策略,根据用户id进行hash之类,让用户落到同一台机器上,但这种很少用,毕竟这个是属于业务的问题)

Redis 5.0部署

半城伤御伤魂 提交于 2020-03-05 18:48:25
前言 redis支持的数据类型: 字符串(string)。 哈希表(hash)。 列表(list)。 集合(set)。 有序集合(zset)。 位图(bitmaps)。 HyperLoglogs、GEO等。 redis特性如下: 速度快:基于内存工作,使用离OS最近的C语言编写,使用单线程架构,预防了多线程可能产生的竞争问题。 基于键值对的数据结构服务器:redis中的值不仅仅可以是字符串,关于其支持的数据类型已经在文章开头列出来了。 丰富的功能: 1.键过期功能,用来实现缓存。 2.发布订阅功能,用来实现消息系统。 3.支持Lua脚本,可以利用Lua创造出新的Redis命令。 4.简单的事务功能,能在一定程度上保证事务的特性。 5.提供了流水线(pipeline)功能,这样客户端能将一批命令一次性传到redis,较少网络开销。 简单稳定。 客户端语言多:支持java、PHP、Python、C、C++、Nodejs等。 数据持久化:redis工作在内存中,支持两种持久化方式:RDB、AOF来写入到硬盘中。 主从复制:Redis提供了复制功能,实现了多个相同数据的redis副本。 高可用和分布式:Redis从2.8版本正式提供了高可用实现redis Sentinel,它能够保证Reids节点的故障发现和故障自动转移,从3.0版本提供了分布式实现Redis Cluster

redis学习总结

旧街凉风 提交于 2020-03-05 10:49:42
什么是redis redis是一个nosql(not only sql不仅仅只有sql)数据库.翻译成中文叫做非关系型型数据库. 关系型数据库:以二维表形式存储数据 非关系型数据库: 以键值对形式存储数据(key, value形式) 是一家意大利的创业公司出的,然后后来这家公司被VMware赞助. redis底层用C语句编写. redis是将数据存放到内存中,由于内容存取速度快所以redis被广泛应用在互联网项目中, redis有点:存取速度快,官方称读取速度会达到30万次每秒,写速度在10万次每秒最有,具体限制于硬件. 缺点:对持久化支持不够良好, 所以redis一般不作为数据的主数据库存储,一般配合传统的关系型数据库使用. redis应用领域 分布式缓存 分布式session 保存博客或者论坛的留言回复等. 总之是用在数据量大,并发量高的情况下 怎么用 redis主要就是使用命令来进行操作,java端在代码中可以使用Jedis来操作redis服务器 redis数据类型 字符串String 列表list redis中使用的是双向循环链表来实现的list,在redis中更像栈 散列Hash 一般应用于将redis作为分布式缓存,存储数据库中的数据对象 集合set set中数据是无序的并且不允许重复 有序集合zset redis会根据分数自动排序,这里可以使用在学生成绩排序,

redis分布式锁可靠吗

断了今生、忘了曾经 提交于 2020-03-05 01:10:00
写在前面的话 2020年2月22日来杭, 杭州天气不错, 晴空万里,气温回暖, 疫情彷佛散去, 而我开始了既定的跳槽, 投简历,刷面试片刻未敢停留。 一周下来也差不多面了10来家公司, 反馈还行, 但是并没有想象中的那么好, 总体来看杭州互联网既没有那么好, 也没有想象的那么槽。 所以小伙伴们适度焦虑就OK, 重要的还是提升自己的硬实力。 下面来讲几个面试碰到的有意思的问题吧。 如何确定分布式锁的释放时间? 描述:就是你在使用分布式锁对代码加一个锁,会不会业务没有执行完,锁释放了? 我脑子一转这种情况肯定不能让他发生,不然不是并发了吗。 此时你需要想一下分布式锁的实现???? setnx??? set? 如果你说setnx我估计是要歇菜的,因为你刚好掉进面试官的一个坑里,我们来看下setnx命令 没有过期时间???没有过期时间意味着锁要我们自己手动释放,看下伪代码 if ( setnx ( 'key' , 1 ) ) { // 1. try{ // 2.业务逻辑 }catch ( Exception e ) { // 3.异常处理 }finally{ // 4. del 'key' } } 假设在上述代码的1或者4处出现异常,或者说是出现error,比如内存溢出,jvm直接不可用,那么这个锁是不是就释放不掉了??别的线程就无法访问这段代码了,这就是死锁的现象。基于这个问题

redis面试题

懵懂的女人 提交于 2020-03-05 00:53:06
什么是redis? Redis全称为:Remote Dictionary Server(远程数据服务),是一个基于内存的高性能key-value数据库。 Redis的数据类型? Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。 Redis相比Memcached有哪些优势? (1) Memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 (2) Redis的速度比Memcached快很多 (3) Redis可以持久化其数据 Redis是单进程单线程的? Redis是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。 一个字符串类型的值能存储最大容量是多少? 512M MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据? redis内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。 Redis 有哪几种数据淘汰策略? volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 volatile-ttl:从已设置过期时间的数据集(server.db[i].expires