如何实现分库分表后的全局唯一 ID?

分库分表后ID的九阳真经:如何让ID像孙悟空的毫毛一样“分身”却永不重复? 分布式ID生成技术综述:如何应对分库分表场景下的ID冲突?本文对比5种主流方案:UUID随机性虽强但排序困难;数据库自增ID简单但扩展性差;雪花算法高性能但依赖时间戳;Redis原子操作可靠但可能成为性能瓶颈;混合ID法综合时间、机器ID与随机数。最佳实践建议根据业务需求选择,如高并发场景推荐雪花算法,全局唯一性要求严格则可考虑Redis方案。每种方法各有优劣,需权衡唯一性、性能和分布式协调成本。(149字) 阅读详情

引言:
在千万级用户规模的系统中,单表数据量突破5000万行后,分库分表成为解决数据库性能瓶颈的关键手段。然而,分库分表后如何生成全局唯一ID却成为新的技术挑战——传统的自增ID在分布式环境下会出现重复,而UUID等方案又存在索引性能差、存储空间大等问题。

作为一名拥有8年经验的Java架构师,我曾为多个大型电商和金融系统设计ID生成方案,深知全局唯一ID在分布式系统中的重要性。今天我将从业务场景出发,深度剖析四种主流方案,并给出生产级实现代码。


一、业务场景与技术挑战

1.1 分库分表后的ID困境

当订单表被水平拆分为1024个分片时:

sql

1.2 技术挑战矩阵

挑战维度

具体问题

全局唯一性

分布式环境下避免ID冲突

有序性

时间有序利于分页查询和索引维护

高性能

支撑10万QPS的ID生成请求

高可用

服务99.99%可用,故障秒级恢复

空间效率

ID长度尽量短(节省存储和索引空间)

信息安全

防止通过ID猜测业务量(如订单量)


二、主流方案深度剖析

2.1 方案全景图

2.2 核心方案对比

方案

优点

缺点

适用场景

UUID

实现简单,本地生成无网络开销

无序(索引性能差),长度长(32字符)

临时数据、非核心业务

Snowflake

趋势递增,高性能,短ID(64位)

依赖机器时钟(时钟回拨问题)

订单系统、日志系统

数据库号段

ID连续,可读性好

存在数据库单点风险

中小规模系统

Redis INCR

性能极高(10万QPS)

需保证Redis高可用

需要极高吞吐的场景

架构师建议:
根据多年实战经验:

电商/金融等核心系统:Snowflake增强版 用户ID等中等吞吐场景:数据库号段+双Buffer优化 临时会话ID等场景:UUIDv4


三、生产级实现方案

3.1 Snowflake增强版(解决时钟回拨)

/**
 * 增强版Snowflake ID生成器
 * 组成:1位符号位 + 41位时间戳 + 10位机器ID + 12位序列号
 * 优化点:时钟回拨解决方案
 */
public class SnowflakeIdGenerator {
    // 起始时间戳(2023-01-01)
    private static final long EPOCH = 1672531200000L;
    private final long workerId; // 机器ID(0-1023)
    private long lastTimestamp = -1L;
    private long sequence = 0L;
    
    // 时钟回拨安全阈值(5ms)
    private static final long MAX_BACKWARD_MS = 5;

    public synchronized long nextId() {
        long currentTimestamp = timeGen();

        // 时钟回拨处理
        if (currentTimestamp < lastTimestamp) {
            long offset = lastTimestamp - currentTimestamp;
            if (offset <= MAX_BACKWARD_MS) {
                // 小范围回拨,等待时钟追平
                waitUntilReach(lastTimestamp);
                currentTimestamp = timeGen();
            } else {
                throw new IllegalStateException(
                    String.format("时钟回拨超过 %dms,拒绝生成ID", MAX_BACKWARD_MS));
            }
        }

        if (lastTimestamp == currentTimestamp) {
            sequence = (sequence + 1) & 0xFFF; // 12位序列号
            if (sequence == 0) {
                // 当前毫秒序列号用尽,等待下一毫秒
                currentTimestamp = waitUntilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }

        lastTimestamp = currentTimestamp;

        return ((currentTimestamp - EPOCH) << 22) 
                | (workerId << 12) 
                | sequence;
    }

    private long waitUntilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    private void waitUntilReach(long targetTime) {
        long current;
        do {
            current = timeGen();
        } while (current < targetTime);
    }

    private long timeGen() {
        return System.currentTimeMillis();
    }
}

关键优化点:

动态WorkerID分配:通过ZooKeeper或配置中心管理机器ID 时钟回拨保护:5ms内小范围回拨自动等待,超过阈值告警 时间戳缓存:避免频繁调用System.currentTimeMillis()

3.2 数据库号段模式(双Buffer优化)

/**
 * 双Buffer号段ID生成器
 * 解决传统号段模式取号延迟问题
 */
public class SegmentIdGenerator {
    private final SegmentService segmentService; // 数据库服务
    private volatile Segment currentSegment = new Segment(0, 0);
    private volatile Segment nextSegment;
    private final Executor executor = Executors.newSingleThreadExecutor();

    // 异步加载下一个号段
    public void init() {
        currentSegment = segmentService.getNextSegment("order");
        executor.execute(this::loadNextSegment);
    }

    public long nextId() {
        if (currentSegment.isExhausted()) {
            if (nextSegment != null) {
                currentSegment = nextSegment;
                executor.execute(this::loadNextSegment);
            } else {
                // 降级:同步加载
                currentSegment = segmentService.getNextSegment("order");
            }
        }
        return currentSegment.getAndIncrement();
    }

    private void loadNextSegment() {
        nextSegment = segmentService.getNextSegment("order");
    }

    static class Segment {
        private final AtomicLong current;
        private final long end;

        Segment(long start, long end) {
            this.current = new AtomicLong(start);
            this.end = end;
        }

        long getAndIncrement() {
            long id = current.getAndIncrement();
            if (id > end) {
                throw new IllegalStateException("Segment exhausted");
            }
            return id;
        }

        boolean isExhausted() {
            return current.get() > end;
        }
    }
}

// 数据库号段服务实现
@Service
public class SegmentService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public Segment getNextSegment(String bizType) {
        // 使用CAS更新号段
        while (true) {
            SegmentRange range = jdbcTemplate.queryForObject(
                "SELECT current_val, step FROM id_segment WHERE biz_type=? FOR UPDATE",
                (rs, rowNum) -> new SegmentRange(
                    rs.getLong("current_val"),
                    rs.getInt("step")),
                bizType);
            
            long newVal = range.currentVal + range.step;
            int updated = jdbcTemplate.update(
                "UPDATE id_segment SET current_val=? WHERE biz_type=? AND current_val=?",
                newVal, bizType, range.currentVal);
            
            if (updated > 0) {
                return new Segment(range.currentVal, newVal - 1);
            }
        }
    }
    
    static class SegmentRange {
        final long currentVal;
        final int step;
        
        SegmentRange(long currentVal, int step) {
            this.currentVal = currentVal;
            this.step = step;
        }
    }
}

性能优化点:

双Buffer机制:当前号段使用80%时异步加载下一号段 CAS更新:避免数据库更新冲突 批量取号:每次取1000个ID,降低DB压力

3.3 Redis原子方案(集群版)

/**
 * 基于Redis Cluster的ID生成器
 * 使用INCRBY原子命令
 */
public class RedisIdGenerator {
    private static final String ID_KEY = "global:id";
    private final RedisTemplate<String, String> redisTemplate;

    // 批量获取ID(减少Redis调用)
    public List<Long> nextIds(int batchSize) {
        // 原子操作增加步长
        Long endId = redisTemplate.opsForValue().increment(
            ID_KEY, batchSize);
        
        if (endId == null) {
            throw new RuntimeException("Redis ID生成失败");
        }
        
        long startId = endId - batchSize + 1;
        return LongStream.rangeClosed(startId, endId)
            .boxed()
            .collect(Collectors.toList());
    }
    
    // 高可用保障
    @PostConstruct
    public void init() {
        // 初始化起始ID
        Boolean setIfAbsent = redisTemplate.opsForValue()
            .setIfAbsent(ID_KEY, "1000000");
    }
}

Redis集群配置要点:

spring:
  redis:
    cluster:
      nodes:
        - 192.168.1.101:7000
        - 192.168.1.102:7000
        - 192.168.1.103:7000
    lettuce:
      pool:
        max-active: 1000 # 连接池优化

四、生产环境最佳实践

4.1 方案选型决策树

A[是否需要有序ID?] -->|是| B[QPS<1万?]
A -->|否| C[使用UUID]
B -->|是| D[数据库号段模式]
B -->|否| E[需要严格控制长度?]
E -->|是| F[Snowflake]
E -->|否| G[Redis方案]

4.2 容灾设计

Snowflake时钟回拨SOP:

  1. 监控报警:检测到时钟回拨立即告警
  2. 自动降级:回拨5ms内自动等待
  3. 人工介入:回拨超过5ms切换备用ID生成器

Redis故障转移方案:

  1. 主从切换:哨兵模式自动故障转移
  2. 降级方案:故障时切到数据库号段模式
  3. 数据恢复:定期持久化ID最大值到DB

4.3 性能压测数据

方案

单机QPS

平均延迟

资源消耗

Snowflake

120,000

0.3ms

低(仅CPU)

数据库号段

25,000

1.2ms

中(DB连接)

Redis

180,000

0.8ms

高(网络带宽)

UUID

95,000

0.1ms

低

压测结论:

超高频场景(如秒杀):优先选择Snowflake 需要连续ID场景:数据库号段+双Buffer 简单临时ID:UUIDv4


五、常见陷阱与解决方案

5.1 Snowflake的坑

问题1:虚拟机时钟回拨频繁
✅ 解决方案:

  • 物理机部署ID生成服务
  • 启用NTP时间同步(最小化时间步进)

问题2:WorkerID分配冲突
✅ 解决方案:

// 通过ZooKeeper分配WorkerID
public class WorkerIdAssigner {
    public int assignWorkerId(String appName) {
        String path = "/snowflake/" + appName;
        if (zkClient.exists(path)) {
            return zkClient.getChildren(path).size();
        } else {
            String node = zkClient.createEphemeralSequential(path + "/worker", null);
            return Integer.parseInt(node.split("-")[1]);
        }
    }
}

5.2 数据库号段的优化

问题:号段用完导致请求堆积
✅ 解决方案:

  • 动态调整step大小(根据QPS实时计算)
  • 低水位预警:使用80%时触发异步加载
/* 动态调整step的SQL */
UPDATE id_segment 
SET step = CASE 
    WHEN qps < 1000 THEN 1000
    WHEN qps < 5000 THEN 5000
    ELSE 20000
END
WHERE biz_type = 'order';

5.3 Redis方案的数据安全

问题:Redis重启导致ID重复
✅ 解决方案:

  1. 开启AOF持久化
  2. 定期备份ID最大值到MySQL
  3. 重启时初始化值 = MAX(Redis持久化值, DB备份值)
# Redis持久化配置
appendonly yes
appendfsync everysec

架构师箴言:
设计全局唯一ID系统时,需谨记三大原则:

业务导向:订单系统需要趋势递增,会话ID只需唯一性 弹性设计:时钟回拨、网络分区、节点故障必须考虑 成本控制:Redis方案性能虽高,但成本是数据库方案的5倍

没有最好的方案,只有最适合业务现状的方案。建议初期采用Snowflake+数据库号段双引擎,后期根据业务增长动态调整。

生物信息学工具链搭建:用conda一键搞定MCScanX所有依赖(Ubuntu20.04实测) 本文详细介绍了在Ubuntu20.04系统上使用conda一键部署MCScanX及其所有依赖的高效方法,解决了传统源码编译安装中的依赖冲突问题。通过conda环境管理工具,研究者可以快速搭建生物信息学工具链,实现基因组共线性分析的高效运行,显著提升研究效率。 阅读详情

相关推荐

一文带你完成ARMv8架构中的cache知识点

【摘要】 在最初开发ARM架构时,处理器的时钟速度和内存的访问速度大致相同。今天的处理器内核要复杂得多,其时钟速度可以快上几个数量级。但是,外部总线和内存设备的频率并没有扩大到同样的程度。有可能实现小块的片上SRAM,它可以以与内核相同的速度运行,但是与标准的DRAM块相比,这种RAM非常昂贵,因为后者的容量可以达到数千倍。在许多基于ARM处理器的系统中,访问外部存储器需要几十甚至几百个内核周期。 cache的技术背景 在最初开发ARM架构时,处理器的时钟速度和内存的访问速度大致相同。今天的处.

ABCCloud的博客 1854

10 | 发号器:如何保证分库分表后ID的全局唯一性?

10 | 发号器:如何保证分库分表后ID的全局唯一性?

chenyong6301567的博客 932

IoTDB时序数据库在Windows下的保姆级安装教程(含环境变量配置避坑指南)

本文提供Apache IoTDB时序数据库在Windows系统下的详细安装与配置指南。教程涵盖从Java环境检查、软件下载解压,到环境变量配置的深度避坑,并详解了服务的启动、停止、连接测试及基础数据操作,帮助物联网开发者在Windows平台快速搭建稳定的时序数据库环境。

weixin_29275257的博客 262

分库分表如何处理主键ID

雪花算法,UUID, 分库分表主键生成算法

CAT 2605

【Python Turtle合集】有趣好玩的代码当然要分享给大家啦~(皮卡丘、玫瑰花、小黄人......)

前言 🚀 作者 :“程序员梨子” 🚀 **文章简介 **:本篇文章主要是写了利用Turtle库绘制四种不一样的图案的小程序! 🚀 **文章源码免费获取 : 为了感谢每一个关注我的小可爱💓每篇文章的项目源码都是无 偿分享滴💓👇👇👇👇 点这里蓝色这行字体自取,需要什么源码记得说标题名字哈!私信我也可! 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 正文 今天给大家介绍一个好玩儿的库,嘻嘻! Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x、纵

TZ45678的博客 3万+

高分影像批处理第三回——RPC文件与几何校正

前言 前面两章部分完成了图像的基本组织和大气校正,可是对于遥感影像地理相关数据,精确的地理坐标也是非常关键的。L1级数据,可惜,并没有帮我们处理地理坐标系统。无论是打开ENVI还是用gdal工具查看图像元数据,其坐标系统都是错误的或者说是未读入的。因此本章节来解决这个问题。

weixin_43762038的博客 1万+

分库分表之后-全局唯一ID

其实这是分库分表之后你必然要面对的一个问题,需要一个全局唯一的 id 来支持 一.全局唯一id–基于数据库的实现方案 1.1 数据库自增 id 这个就是说你的系统里每次得到一个 id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个 id。拿到这个 id 之后再往对应的分库分表里去写入。 这个方案的好处就是方便简单,谁都会用;缺点就是单库生成自增 id,要是高并...

白天不懂夜的黑的博客 1085

【感知模块算法】障碍物detect+trace+prediction方向介绍

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、多维度看感知问题,体会复杂性二、障碍物/环境目标detect方向1.视觉目标检测方向(1)图像处理认知(2)视觉基础理论部分1、获取数据集---python网页爬虫、买数据、自己录数据、使用开源比赛的数据集2、opencv库的学习3、深度学习框架学习(3)视觉目标检测理论(1)目标检测的概念(2)目标检测的应用场景(3)现有目标检测框架原理及论文【这仅仅是我当初入门学习的框架~

qq_35635374的博客 2894

发号器:如何保证分库分表后ID的全局唯一性?

发号器:如何保证分库分表后ID的全局唯一性?数据库的主键要如何选择?基于 Snowflake 算法搭建发号器总结 我们通过分库分表和主从读写分离的方式解决了数据库的扩展性问题,但是在,数据库在分库分表之后,我们在使用数据库时存在的许多限制,比如说查询的时候必须带着分区键;一些聚合类的查询(像是 count())性能较差,需要考虑使用计数器等其它的解决方案,其实分库分表还有一个问题,就是主键的全局唯一性的问题。 数据库的主键要如何选择? 数据库中的每一条记录都需要有一个唯一的标识,依据数据库的第二范式,数据库

zhanglu0302的博客 861

Linux系列:SecurtCRT中的密码如何找回

【代码】Linux系列:SecurtCRT中的密码如何找回。

NIO4444 1086

【LAMMPS学习】八、基础知识(4.5)TIP5P水模型

​ 五点 TIP5P 刚性水模型通过添加两个通常无质量的附加位点 L 来扩展three-point TIP3P model,其中放置与氧原子相关的电荷。这些位点 L 位于距氧原子固定距离处,形成从 HOH 平面旋转 90 度的四面角。因此,这些位点在某种程度上近似于氧的孤对,从而改善了水结构,与four-point TIP4P model相比变得更加“四面体”。

荷塘阅色 1421

全局唯一递增的id_高并发环境下系统生成全局唯一ID

最近在proxy的分库分表,需要给表中的主字段产生一个全局唯一ID,考虑到后期DBA会拿这个ID做索引的,所以产生的这个ID也要尽可能的有序, 总体要求如下不能有单点问题...全局唯一且有序尽量64位可以表示于是乎调研了一下, 貌似有几个典型的代表twitter的snowflake生成方式:41位的时间序列(ms, 大约可以用69年)10位的机器标志(大约可以支持部署1024台机器, 5bit设...

weixin_39977586的博客 349

PyMuPDF为PDF文件添加注释

我将介绍如何使用PyMuPDF库来为PDF文件添加注释,包括文本注释、高亮注释、下划线注释等15种注释的使用方法。

布啦啦 2243

如何生成全局唯一id

这些项目提供了丰富的功能和灵活的配置选项,可以帮助你生成数据库唯一 ID,确保分库分表的主键不重复。根据你的具体需求,可以选择合适的项目进行集成和开发。SnipID 是一个现代化、灵活的短 ID 生成器,支持分布式场景、ID 解析和多种随机策略。UidGenerator 是百度开源的一个基于 Snowflake 算法的唯一 ID 生成器。Snowflake 是一个经典的分布式 ID 生成算法,广泛用于生成全局唯一 ID。Leaf-segment 是 Leaf 的一个分支,专注于生成递增的段 ID。

红豆和绿豆的博客 1337

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

深度学习工具包 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")

分布式全局唯一ID生成方案

     当业务量上升到一定程度,数据量暴增的时候,分库分表将是我们必然要面对的一个问题。那么问题就来了,就是id如何生成?因为要是分成多个表之后,每个表都是从1开始累加,那肯定不对啊,需要一个全局唯一的id来支持。所以这便成了我们在实际生产环境中必须考虑的问题。      我们应该采用哪种适合自己的解决方案呢?这个是十分重要的。下面我将列举一些,不一定全部适合你,这些解决方案仅供你参考,或许也...

Franky 597

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Mysql分库分表技术难题之分布式全局唯一id解决方案

https://www.toutiao.com/a6625815754279223812/?tt_from=mobile_qq&amp;utm_campaign=client_share&amp;timestamp=1549519373&amp;app=news_article&amp;utm_source=mobile_qq&amp;iid=59568063679&amp;utm_medium=...

azhuyangjun的博客 908

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

分库分表之后,id 主键如何处理

其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 开始累加,那肯定不对啊,需要一个全局唯一的 id 来支持。所以这都是你实际生产环境中必须考虑的问题。 基于数据库的实现方案 数据库自增 id 这个就是说你的系统里每次得到一个 id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个 id。拿到这个 id 之后再往对应的分库分表里去写入。 这个方案的好处就是方便简单,谁都会用;缺点就是单库生成自增 id,要是高并发的

OuNuo5280的博客 483

分布式系统的唯一id生成算法你了解吗?

  在分库分表之后你必然要面对的一个问题,就是id咋生成?   因为要是一个表分成多个表之后,每个表的id都是从1开始累加自增长,那肯定不对啊。   举个例子,你的订单表拆分为了1024张订单表,每个表的id都从1开始累加,这个肯定有问题了!   你的系统就没办法根据表主键来查询订单了,比如id = 50这个订单,在每个表里都有!   所以此时就需要分布式架构下的全局唯一id生成的方案了,...

qianfeng_dashuju的博客 149

分库分表全局ID方案(一)

大型网站数据量庞大,为了能增加数据存储量,提升读写效率,数据库分库分表是常见的一种方案。但是这样同时也带来了一些问题,比如分库分表后如何保证主键ID的自增以及唯一。 自增ID+replace into利用mysql自带的主键id自增功能,使用replace into语句更新生成全局ID。CREATE TABLE `t_id` ( `id` bigint(20) NOT NULL AUTO_

搞搞搞技术的 2897

分库分表之后,id 主键如何处理?

分库分表之后,id 主键如何处理? 因为要是分成多个表之后,每个表都是从 1 开始累加,这样是不对的,我们需要一个全局唯一的 id 来支持。 生成全局 id 有下面这几种方式: UUID 不适合作为主键,因为太长了,并且无序不可读,查询效率低。比较适合用于生成唯一的名字的标示比如文件的名字。 数据库自增 id 两台数据库分别设置不同步 ,生成不重复ID的策略来实现高可用。这种方式生成的 id 有序,但是需要独立部署数据库实例,成本高,还会有性能瓶颈。 利用 redis 生成 id 性能比较好,灵活方便,不依

Kirito的博客 897

雪花算法id长度_如何保证 ID 的全局唯一性?

如何保证 ID 的全局唯一性?分库分表之后如何生成全局唯一的数据库主键呢?数据库中的主键如何选择?数据库中的每条记录都需要有一个唯一的标识,根据数据库第二范式,数据库中每个表都需要唯一主键,其他元素和主键一一对应。一般有两种选择方式:使用业务字段作为主键,比如用户表来说,可以使用手机号, email ,或者身份证作为主键。使用唯一 ID 作为主键如果使用唯一 ID 作为主键,就需要保证 ID 的全...

weixin_39947908的博客 919

几种分库分表后全局id生成方案

假设,在2175/11/7 12:12:14时间里,机房17的机器25,发送了第二条消息,snowflake算法服务,会发现说机房17的机器25,在2175/11/7 12:12:14时间里,在这一毫秒,之前已经生成过一个id了,此时如果你同一个机房,同一个机器,在同一个毫秒内,再次要求生成一个id,此时我只能把加1。twitter开源的分布式id生成算法,把一个64位的long型的id,1个bit是不用的,用其中的41 bit作为毫秒数,用10 bit作为工作机器id,12 bit作为序列号。

通往IT大道的专栏 612

分布式02 - 全局唯一ID实现方案

分布式02 - 全局唯一ID实现方案

qq_43350524的博客 1091
上一篇: Docker的时代已经落幕了吗?
下一篇: MyBatis Plus 如何优化千万级数据的 CRUD?
程序员职业指南
博客等级 码龄4年 2136粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值