Redis深度历险(4)-分布式锁原理与实现

【Redis实战】分布式锁 Redis分布式锁 阅读详情

分布式锁有两种经典的实现,一种是Zookeeper实现,另一种就是Redis实现了,下面简单介绍分布式锁原理以及Redis实现

1.1 什么是分布式锁

分布式锁(Distributed Locks)一词给人的第一种感觉就是一种深不可测的、高大上的感觉:

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

其实仔细了解后发现,分布式锁其实就是两块内容,一是分布式特性,这也是分布式锁相较于普通的锁来说需要解决的问题,二是锁特性,锁特性就如平常的同步锁、互斥锁一样 分布式锁首先要解决的问题,是多个系统中如何保证对同一资源的使用一致性,也就是对这个资源上锁,并且让其他系统也可立刻感知到这把锁的存在,从而阻塞或者自旋等待锁。以下两张图可以直观的感受这个过程:

在这里插入图片描述

在这里插入图片描述

1.2 SETNX KEY VALUE命令

Redis能实现分布式锁的原因在于它具有一条原子性命令:SETNX KEY VALUE,即KEY不存在时则插入VALUE,返回1;若KEY存在,则插入失败,返回0。这就是一个锁的请求过程:若不存在KEY这个锁,则获取这个锁(插入一条以KEY标识的字符串);若存在KEY这个锁,则原地自旋请求至成功或超时退出。

127.0.0.1:6379> setnx dis-lock test
(integer) 1 						//获取锁成功
127.0.0.1:6379> setnx dis-lock test
(integer) 0  						//获取锁失败

由于SETNX命令是原子性的,所以不会出现获取锁时的并发问题而导致判断失误,重复地获取锁,但是这种方法有一个致命的问题:如果系统A给一个资源上了锁,但是A系统发生崩溃导致无法释放锁,这样就导致了死锁问题,若没有外力作用则其他系统都将无法获取到该锁,而只能等待,这可能会导致整个系统的崩坏。

1.3 EXPIRE KEY EXPIRE_TIME命令

为了解决上面可能出现的死锁问题,我们可以在获取锁之后,给该锁一个过期时间,这样就可以避免系统出现问题而无法释放锁而导致的死锁问题:

127.0.0.1:6379> setnx dis-lock test
(integer) 1 						//获取锁成功
127.0.0.1:6379> expire dis-lock 10
(integer) 1 						//设置过期时间为10s
127.0.0.1:6379> setnx dis-lock test
(integer) 0 						//上锁的系统崩溃,无法释放锁,其他系统获取该锁失败
127.0.0.1:6379> setnx dis-lock test
(integer) 1 						//在10S后锁过期,其他系统正常获取该锁

那么SETNX命令和EXPIRE命令配合使用是否可以实现一个完善的分布式锁呢?答案是不能。我们可以设想以下,如果A系统获取锁成功,但是在设置过期时间时发送错误,那么该锁仍然不会过期,这样子就又重复了上面的那个情况。解决办法是让SETNX命令和EXPIRE命令具备原子性。

1.4 SET KEY VALUE EX EXPIRE_TIME NX命令

这个命令是Redis 2.8中,作者为了解决SETNX和EXPIRE命令的原子性问题而产生的,现在通过这个命令,就可以使SETNX和EXPIRE命令统一成一个原子命令:若锁不存在,则一定会添加锁并且设置过期时间;

127.0.0.1:6379> set dis-lock test ex 10 nx
OK											//获取锁并且设置过期时间
127.0.0.1:6379> set dis-lock test ex 10 nx
(nil)									  //获取锁失败
127.0.0.1:6379> set dis-lock test ex 10 nx
OK											//获取锁失败

1.5 使用Jedis实现分布式锁

  • JedisUtil
package redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisException;

/**
 * @Auther: ARong
 * @Date: 19-9-28 下午1:01
 * @Description:
 **/
public class JedisUtil {
    private static JedisPool pool = null;
    static {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(500);
        config.setMaxIdle(5);
        config.setMaxWaitMillis(10 * 1000);
        config.setTestOnBorrow(true);
        pool = new JedisPool(config, "127.0.0.1", 6379, 10 * 1000);
    }

    /**
     * @auther: Arong
     * @description: 从连接池中获取Jedis
     * @param: []
     * @return: redis.clients.jedis.Jedis
     * @date: 下午1:02 19-9-28
     */
    public static Jedis getJedis() {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
        } catch (JedisException e) {
            e.printStackTrace();
        } finally {
            pool.returnBrokenResource(jedis);
        }
        return jedis;
    }
}

  • RedisDistributedLock
package redis;

import redis.clients.jedis.Jedis;
import java.util.logging.Logger;

/**
 * @Auther: ARong
 * @Date: 19-9-28 下午1:45
 * @Description: Redis 分布式锁实现
 **/
public class RedisDistributedLock {
    private final static Logger logger = Logger.getLogger(String.valueOf(RedisDistributedLock.class));
    //每次请求的时间为200ms
    private  Long PER_REQ_MILL = null;
    //总体等待时间不超过10s
    private  Long WAIT_TIME_OUT = null;
    //锁名称
    private  String LOCK_NAME = null;
    //锁过期时间
    private Long EXPIRE_TIME = null;

    public RedisDistributedLock() {
        LOCK_NAME = Thread.currentThread().getName();
        PER_REQ_MILL = 200l; //默认每次自旋请求间隔200ms
        WAIT_TIME_OUT = 10 * 1000l; //默认自旋时间10s
        EXPIRE_TIME = 2 * 1000l;//默认过期时间2s
    }

    public RedisDistributedLock(String lockName, Long perReqMill, Long waitTimeOut, Long expireTime) {
        LOCK_NAME = lockName;
        PER_REQ_MILL = perReqMill;
        WAIT_TIME_OUT = waitTimeOut;
        EXPIRE_TIME = expireTime;
    }

    /**
     * @auther: Arong
     * @description: 获取锁/上锁,不成功则原地自旋
     * @param: [lockName]
     * @return: void
     * @date: 下午1:49 19-9-28
     */
    public void lock() {
        //先用set key value nx ex expireAt 命令查询是否已经有了该锁
        Jedis jedis = JedisUtil.getJedis();
        String isSet = jedis.set(this.LOCK_NAME, this.LOCK_NAME, "NX", "EX", this.EXPIRE_TIME / 1000);
        if ("OK".equals(isSet)) {
            //没有该锁,则直接占用
            logger.info("<<<<<线程" + Thread.currentThread().getName() + "占用" + this.LOCK_NAME + "锁成功");
            return;
        } else {
            //该锁仍然存在,原地自旋,每隔一段时间请求一次,直至成功或超时抛出错误
            spin();
        }
    }

    /**
     * @auther: Arong
     * @description: 原地自旋,每隔 perReqMill 毫秒进行一次请求, 总体超时时间为 waitTimeOut 毫秒
     * @param: [lockName, perReqMill, waitTimeOut]
     * @return: void
     * @date: 下午2:13 19-9-28
     */
    private void spin() {
        //进入时的时间
        long beginTime = System.currentTimeMillis();
        //获取锁
        Jedis jedis = JedisUtil.getJedis();
        String isSet = jedis.set(this.LOCK_NAME, this.LOCK_NAME, "NX", "EX", this.EXPIRE_TIME / 1000);
        if ("OK".equals(isSet)) {
            //没有该锁,则直接占用
            logger.info("<<<<<线程" + Thread.currentThread().getName() + "占用" + this.LOCK_NAME + "锁成功");
        } else {
            while (true) {
                try {
                    //睡眠短暂时间继续请求
                    Thread.sleep(this.PER_REQ_MILL);
                    logger.info("线程"+Thread.currentThread().getName()+"自旋睡眠"+this.PER_REQ_MILL+"毫秒");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (System.currentTimeMillis() - beginTime >= this.WAIT_TIME_OUT) {
                    //已经超时
                    logger.info("线程"+Thread.currentThread().getName()+"超过了" + this.WAIT_TIME_OUT + "毫秒都无法获取到名为"+this.LOCK_NAME+"的锁,超时退出");
                    throw new RuntimeException("获取锁失败");
                } else {
                    //没有超时,继续请求
                     isSet = jedis.set(this.LOCK_NAME, this.LOCK_NAME, "NX", "EX", this.EXPIRE_TIME / 1000);
                    if ("OK".equals(isSet)) {
                        //上锁成功
                        logger.info("<<<<<线程" + Thread.currentThread().getName() + "占用" + this.LOCK_NAME + "锁成功");
                        break;
                    }
                }
            }
        }
    }


    /**
     * @auther: Arong
     * @description: 解锁
     * @param: [lockName]
     * @return: void
     * @date: 下午2:39 19-9-28
     */
    public void unlock() {
        Jedis jedis = JedisUtil.getJedis();
        //先获取该锁
        String lockValue = jedis.get(this.LOCK_NAME);
        if (lockValue == null) {
            logger.info(">>>>>" + Thread.currentThread().getName() + "解除了对" + this.LOCK_NAME + "的占用");
            return;
        } else if (this.LOCK_NAME.equals(lockValue)){
            Long del = jedis.del(this.LOCK_NAME);
            logger.info(">>>>>"+Thread.currentThread().getName() + "解除了对" + this.LOCK_NAME + "的占用");
            return;
        }
        logger.info("*****"+Thread.currentThread().getName() + "无法解除对" + this.LOCK_NAME + "的占用");
    }
}
  • 测试
    首先模拟自旋获取锁成功的情况:
 @Test
    public void fun() throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.submit(() -> {
          //设置每500ms请求自旋一次,超时时间为5s,锁过期时间为5s
            RedisDistributedLock lock1 = new RedisDistributedLock("lock", 500l, 10 * 1000l, 5 * 1000l);
            lock1.lock();
            try {
                //占用锁4s钟
                Thread.sleep(4 * 1000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock1.unlock();
        });

        RedisDistributedLock lock2 = new RedisDistributedLock("lock", 500l, 10 * 1000l, 5 * 1000l);
        lock2.lock();
        Thread.sleep(2000l);
        lock2.unlock();
    }

在这里插入图片描述

接下来模拟自旋超时的情况:

@Test
    public void fun3() throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.submit(() -> {
            //设置每500ms请求自旋一次,超时时间为5s,锁过期时间为5s
            RedisDistributedLock lock1 = new RedisDistributedLock("lock", 500l, 5 * 1000l, 5 * 1000l);
            lock1.lock();
            try {
                //占用锁3s钟
                Thread.sleep(3 * 1000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock1.unlock();
        });
        //请求超时时间2s
        RedisDistributedLock lock2 = new RedisDistributedLock("lock", 500l, 2 * 1000l, 5 * 1000l);
        lock2.lock();
        Thread.sleep(2000l);
        lock2.unlock();
    }

在这里插入图片描述

关于Redis分布式锁的问题其实还有很多可以细究的,例如但是由于个人需求以及技术限制,目前就看到这里吧!

基于Redis的分布式锁实现方案 文章目录传统方式利用setnx+expire命令(错误做法)利用lua脚本利用set key value px milliseconds nxRedlock 传统方式 利用setnx+expire命令(错误做法) Redis的setnx命令 setnx key value 将key设置为value,当键不存在时,才能成功,若键存在,什么也不做,成功返回1,失败返回0 。 setnx实际上就是SET IF NOT Exists的缩写。 expire命令 expire key timeout 将key的 阅读详情

相关推荐

Redis 深度历险: 核心原理和应用实践

1.Redis 可以做什么? Redis 的业务应用范围非常广泛,让我们以掘金技术社区(juejin.im)的帖子模块为实 例,梳理一下,Redis 可以用在哪些地方? 1、记录帖子的点赞数、评论数和点击数 (hash)。 2、记录用户的帖子 ID 列表 (排序),便于快速显示用户的帖子列表 (zset)。 3、记录帖子的标题、摘要、作者和封面信息,用于列表页展示 (hash)。 ...

ashylya的博客 2622

Redis 分布式锁

当服务采用集群方式部署的时候,本地锁无法发挥作用,所以需要分布式锁来实现加锁。 实现 Redis主要运用setnx命令进行锁操作 加锁: SETINX key value, 当锁不存在的时候,成功设置锁并返回 解锁: DEL key, 通过删除键值对释放锁,以便其他线程可以通过SETINX来获取锁 锁超时:EXPIRE key timeout, 设置超时时间,以便即使锁没有被及时释放,也可以在一定时间内自动释放,避免资源被永远锁住 Redis使用lua脚本的好处 减少网络开销。可以将多个请求通过脚本形

iUcool的博客 368

Redis深度历险:核心原理和应用实践带你由入门走向精通

前言 Redis作为目前的主流NoSql数据库,不会是不可能的,在面试中也是非常高频的,一定不能在这个环节丢分,不管是学习,还是面试,以下知识点,都有必要掌握。 下面给大家带来一份Redis深度历险:核心原理和应用实践pdf文档 展示: 目录 开篇:Redis可以用来做什么? 基础:Redis基础数据结构 应用 应用一:千帆竞发--分布式锁 应用二:缓兵之计--延时队列 应用三:节衣缩食--位图 应用四:四两拨千斤--HyperLogLog 应用五:层峦...

javajavajava 1149

redis分布式锁(一)set NX实现

最近是一直在研究redis,本篇则主要想谈谈对redis的锁的理解。 使用redis常用的两种加锁的机制: SETNX命令 SET命令 一、SETNX实现 SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。 SETNX key value 将 key 的值设为 value ,当且仅当 key 不存在。 若给定的 key 已经存在,则 SETNX 不做任何动作。 127.0.0.1:6379> SETNX test 'try' (integer) 1 127.

不管风吹浪打,胜似闲庭信步 3万+

Redis进阶深度历险:核心原理与高阶实战全解析

save 900 1 # 15分钟内至少1次更改save 300 10 # 5分钟内至少10次更改save 60 10000 # 1分钟内至少10000次更改Redis内部维护一个计时器数组,记录每个规则上次满足的时间。每当有写命令执行,服务器会更新dirty计数器,并检查是否满足任一save条件。若满足,则自动执行BGSAVE。

weixin_32252929的博客 1021

2025最新正版Autodesk 3ds Max 2022安装教程:从下载到中文环境配置全流程解析

Autodesk 3ds Max 2022是一款专业的三维建模、动画和渲染软件,广泛应用于影视制作、游戏开发、建筑可视化等领域。

waicsdn_haha的博客 1万+

Jedis方法参数说明

import java.util.List; import java.util.Map; import java.util.Set; /** * Common interface for sharded and non-sharded Jedis */ public interface JedisCommands { /** * 存储数据到缓存中,若key已存在则覆盖 v...

小白的学习之路 1642

从ESP/ABS选型看轮速传感器:为什么你的车用了AK+PWM+7/14mA三种协议?

本文深入解析了汽车轮速传感器的三种主流协议(7/14mA电流型、PWM型和AK协议型)及其混合应用场景。通过对比不同协议的技术特点、成本效益和工程挑战,揭示了现代车辆采用多种传感器协议背后的设计逻辑,包括成本控制、性能平衡和冗余设计等关键因素。

weixin_29266679的博客 534

《Redis深度历险核心原理与应用实践》读书笔记

目录前言基础和应用篇Redis可以做什么5种基础数据结构位图HyperLogLog布隆过滤器限流附件的人或物(GEO)scan原理篇集群篇拓展篇保护Redis 前言 《Redis深度历险核心原理与应用实践》是掌阅服务端技术专家钱文品所著,看完后感觉有点东西。书马上要还了,避免忘记,在此与自己所学结合做个笔记。不涉及源码篇(因为这块没怎么看懂)。 基础和应用篇 Redis可以做什么 1、缓存最近热帖内容(hash)。 2、分布式锁(hash、string)。 3、记录帖子的点赞数,评论数和点击数(has

愤怒的苹果ext的博客 1489

保姆级教程:手把手教你用Jacquard V2数据集训练机器人抓取模型(附完整代码)

本文提供了一份详细的保姆级教程,手把手教你使用Jacquard V2数据集训练机器人抓取模型。从环境配置、数据准备到模型架构设计、训练优化和实际部署,全程解析并附完整代码,帮助开发者快速掌握视觉抓取技术。

weixin_29031057的博客 315

2026华为OD机试真题 9月27日 新系统 【均衡调度】

华为OD机试真题 新系统 9月27号【均衡调度】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【均衡调度】多语言题解。

qq_45776114的博客 1771

Redis深度历险:掌握核心原理与应用实践

Redis深度历险:掌握核心原理与应用实践 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在当今大数据和云计算的时代,高效的数据存储和处理技术显得尤为重要。Redis,作为一种高性能的键值存储系统,凭借其卓越的性能和丰富的功能,成为了众多开发者和企业的首选。为了帮助广大开发者深入理解和掌握Redis的核心原理与应用实践,我们特别推出了《Redis深度历险:核心原理和应...

gitblog_06645的博客 357

使用 Fargate 在 AWS ECS 上运行 Spring Boot 应用程序

本文介绍了使用AWS Fargate支持的ECS部署SpringBoot应用的完整流程。主要内容包括:1)将SpringBoot应用打包为Docker镜像并推送至ECR;2)创建任务定义配置CPU、内存和网络等参数;3)设置ECS服务管理任务运行;4)配置负载均衡器分配流量;5)设计VPC网络和安全组规则确保安全访问;6)使用SSM参数存储管理敏感信息。整个过程实现了无服务器化部署,既保持了应用控制权,又免除了基础设施管理负担,是扩展Web服务的可靠方案。

介绍AWS Azure GCP devops Terraform 等技术 513

redis深度历险 pdf_Redis深度历险

说明:本文章为书籍《Redis深度历险》的读书笔记,如有侵权,马上删除,不承担任何法律责任。目录:应用原理集群拓展源码应用内容列表:ZSET,分布式锁,HyperLogLog,布隆过滤器1.ZSET 有序列表 sorted set形式value 1 - score 1value 2 - score 2value 3 - score 3数据结构value -> score : HashMaps...

weixin_39787792的博客 1537

YOLOv11改进 ,YOLOv11改进主干网络为MobileNetV3,助力涨点

MobileNetV3通过结合硬件感知网络架构搜索(NAS)和NetAdapt算法,通过新颖的架构改进进一步提升了性能。本文开始探讨了自动化搜索算法与网络设计如何协同工作,以利用互补方法来提升整体技术水平。通过这一过程,创建了两个新的MobileNet模型:MobileNetV3-Large和MobileNetV3-Small,分别针对高资源和低资源使用场景。这些模型随后被适配并应用于目标检测和语义分割任务。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 1940

【目标检测】基于yolov5的水下垃圾检测(附代码和数据集,7684张图片)

【目标检测】基于yolov5的水下垃圾检测(附代码和数据集)

学无止境、积少成多、厚积薄发 4183

Redis深度历险-Redis分布式锁

原子操作 原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何context switch线程切换 分布式锁 分布式锁本质上要实现的目标就是在 Redis 里面占一个“茅坑”,当别的进程也要来占时,发现已经有人蹲在那里了,就只好放弃或者稍后再试;对于执行时间超过锁定时间的,需要锁具有重入性 Java 版本的可重入锁(基于ThreadLocal和引用计数) public class RedisWithReentrantLock { priva.

樊先知樊先知的博客 232

从零开始学习CANoe(三)—— 系统变量的创建和使用

从零开始学习CANoe(三)—— 系统变量的创建和使用

蚂蚁小兵 1万+

学习《Redis深度历险:核心原理和应用实践》的总结(上)

对《Redis深度历险:核心原理和应用实践》(作者:钱文品)这本书的知识进行了自己的理解总结。 目录数据结构字符串数据结构list(列表)内部实现:快速列表hash(哈希)set(集合)zset(有序列表)内部实现:跳表分布式锁解决setnx(抢锁)和expire(给锁设置过期时间,防死锁)的原子操作问题解决业务时长超过锁过期时间的问题redis实现队列利用list实现异步消息队列解决队列空了导致客户端不断调用pop()、产生浪费资源的空轮询问题解决sleep导致的消息延迟问题利用zset实现延时队列Hy

weixin_45887086的博客 203

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

读书笔记 - 《Redis 深度历险:核心原理与应用实践》

不过你也不必过于担心,因为 Redis 对 HyperLogLog 的存储进行了优化,在计数比较小时,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大、稀疏矩阵占用空间渐渐超过了阎值时,才会一次性转变成稠密矩阵,才会占用 12KB的空间。数据段是由很多操作系统的页面组合而成,当父进程对其中一个页面的数据进行修改时,会将被共享的页面复制一份分离出来,然后对这个复制的页面进行修改,每个页面的大小只有 4KB。用户看到错误对话框后,会先阅读对话框的内容,再点击重试,这样就可以起到人工延时的效果。

风中的默默 1690

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

redis深度历险:核心原理与应用全书总结

1.redis的类型有string,list,hash,set,zset 2.list类似java的linkedlist,内部是链表不是数组,这意味着插入删除操作非常快,查询相对比较慢 Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符 串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理 hash (字典) Redis 的字典相当于...

ashylya的博客 726

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

redis 深度历险:核心原理与应用实践_编程好书推荐《Redis 深度历险:核心原理与应用实践》...

今天看到一本书,叫《Redis 深度历险:核心原理与应用实践》,作者叫钱文品(老钱),目前在掌阅科技出任资深开发工程师,这本书对redis的剖析还是挺深入的对redis感兴趣的朋友可以买来看看目录如下:第1篇 基础和应用篇 / 11.1 授人以鱼不如授人以渔 / 11.1.1 由 Redis 面试想到的 / 11.1.2 本书的内容范围 / 21.1.3 Redis 可以做什么 / 31.1.4 ...

weixin_39806065的博客 158

【《Redis深度历险》读书笔记(4)】应用(1-4)分布式锁、延时队列、位图、HyperLogLog

本章主要主要介绍了Redis 分布式锁、延时队列、位图、HyperLogLog的应用。

小C的博客 649

膜拜!这份技术点拉满的Redis深度历险笔记,价值百万!

前言 Redis,是互联网技术架构在存储系统中使用最为广泛的中间件,它也是工程师技术面试中最喜欢问的技能之一,特别是那些优秀的、竞争激烈的大型互联网公司(比如 Twitter、新浪微博、阿里云、腾讯云、淘宝、知乎等),通常要求面试者不仅仅掌握Redis基础使用,更要求深层理解Redis内部实现的细节原理。毫不夸张地说,能把Redis的知识点全部吃透,你的半只脚就已经踏进心仪公司的大门! 所以小编给大家整理了这份《Redis深度历险》文档,并且将从目录,前言,主要内容,这三个部分大家讲解这本文档,同时希

bieber007的博客 1491

Redis 深度历险:核心原理与应用实践-0

开篇:授人以鱼不若授人以渔 —— Redis 可以用来做什么? Redis 是互联网技术领域使用最为广泛的存储中间件,它是「Remote Dictionary Service」的首字母缩写,也就是「远程字典服务」。Redis 以其超高的性能、完美的文档、简洁易懂的源码和丰富的客户端库支持在开源中间件领域广受好评。国内外很多大型互联网公司都在使用 Redis,比如 Twitter、YouPorn、...

wangbaolongaa的专栏 475

redis深度历险 pdf_膜拜!这份技术点拉满的Redis深度历险笔记,价值百万!

前言Redis,是互联网技术架构在存储系统中使用最为广泛的中间件,它也是工程师技术面试中最喜欢问的技能之一,特别是那些优秀的、竞争激烈的大型互联网公司(比如 Twitter、新浪微博、阿里云、腾讯云、淘宝、知乎等),通常要求面试者不仅仅掌握Redis基础使用,更要求深层理解Redis内部实现的细节原理。毫不夸张地说,能把Redis的知识点全部吃透,你的半只脚就已经踏进心仪公司的大门!所以小编给大家...

weixin_39851008的博客 246
上一篇: 数据结构(11)-UnionFind(并查集)的实现与优化
下一篇: 剑指Offer(9)-位运算问题
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值