snowflake

Java秒杀系统优化的工程要点

让人想犯罪 __ 提交于 2019-11-30 12:48:21
这篇博客是笔者学习慕课网若鱼老师的《Java秒杀系统方案优化 高性能高并发实战》课程的学习笔记。若鱼老师授课循循善诱,讲解由浅入深,欢迎大家支持。 本文记录课程中的注意点,方便以后code review。此外,本文将注意点相关的优质讲解链接在了一起,方便初学者系统学习。 > 本文并非单纯介绍秒杀系统特有的技术点,不适合高手。进阶学习的话,极客时间有个不错的小专栏——如何设计一个秒杀系统,阿里高级技术专家讲解秒杀系统的设计要点,那个课程挺干货的。 设计秒杀系统的技术要点 1. 登录的密码传输: 用户的数据库表设计,需要增加一字段保存密码的Salt值 两次MD5操作( 敏感数据一定要使用https协议传输 ): 客户端:将明文password和客户端硬编码的Salt值进行拼接,然后进行MD5操作。 > 不用盐的话,MD5字符串有可能会被彩虹表或者社工库破解 服务端:将客户端传过来的MD5字符串和数据库用户对应的Salt字段进行拼接。然后进行MD5操作。 > 这次加盐MD5,可以有效防止内部员工泄露或者数据库被拖库后,明文密码泄露 2. 自定义JSR303的校验器 可以参照javax.validation.constraints.NotNull注解,自定义自己的校验器,将校验代码与业务代码分离。不过由于校验失败会输出BindException异常,所以最好配合全局捕获异常进行友好的输出。

MySQL设置主键的值为UUID

﹥>﹥吖頭↗ 提交于 2019-11-29 00:03:53
在现实的开发中,我们很少用到让MySQL自己生成uuid,因为在高并发场景下,这是不被允许的。通常是在代码中生成id,或者是使用专业的id服务器( Twitter-Snowflake )。我们要讨论的内容是,当我们在手动输入元数据的时候,如果恰巧有一列uuid,我们不想手动输入,而是希望MySQL为我们自动创建,那么我们可以使用触发器。 DELIMITER ;; CREATE TRIGGER `foo_before_insert` BEFORE INSERT ON `foo` FOR EACH ROW BEGIN IF new.id IS NULL THEN SET new.id = uuid(); END IF; END;; DELIMITER ; 最后,希望您谨慎地使用触发器、视图、外键等等,它们都会影响MySQL的性能。 本文的sql来自: MySQL set default id UUID 来源: https://my.oschina.net/hengbao666/blog/3099659

云端数据仓库的模式选型与建设

二次信任 提交于 2019-11-28 21:50:23
数据,对一个企业的重要性不言而喻,如何利用好企业内部数据,发挥数据的更大价值,对于企业管理者而言尤为重要。作为最传统的数据应用之一,数据仓库在企业内部扮演着重要的角色,构建并正确配置好数据仓库,对于数据分析工作至关重要。一个设计良好的数据仓库,可以让数据分析师们如鱼得水;否则可能使企业陷入无休止的问题之中,并在未来的企业竞争中处于劣势。 随着越来越多的基础设施往云端迁移,数据仓库是否也需要上云?上云后能解决常见的性能、成本、易用性、弹性等诸多问题吗?如果考虑上云,需要注意哪些方面?目前主流云厂商产品又有何特点?面对上述问题,本文尝试给出一些答案,供各位参考。本文部分内容参考了MIT大学教授David J.DeWitt的演讲材料。 一、数据仓库建设 数据仓库(DW)的建设方式有很多种,企业可以根据自身需求进行选择。下图简单罗列了主要的DW建设方案并做出扩展对比。 1.1 建设方案 1)商业方案 商业方案,是最为传统的一种,也是过去20~30年的主流方式。企业外购数仓,包括软、硬件一体交付。其典型产品很多,多为国际知名大厂,国产厂商也有部分。 2)自建+开源 这是很多互联网公司通常采用的方案,通过自建底层基础设施+部署开源软件方式完成。整个方案对企业完全自主可控,但对自有人员技术要求较高。颇为典型的产品就是GreenPlum。 3)云+开源 这是上一种方案的变体

【迁移2018-05-08 14:14:27】全局唯一ID生成

会有一股神秘感。 提交于 2019-11-27 19:20:30
唯一ID生成 全局唯一ID 《高并发分布式系统中生成全局唯一Id汇总》 Twitter 方案(Snowflake 算法):41位时间戳+10位机器标识(比如IP,服务器名称等)+12位序列号(本地计数器) Flicker 方案:MySQL自增ID + "REPLACE INTO XXX:SELECT LAST_INSERT_ID();" UUID:缺点,无序,字符串过长,占用空间,影响检索性能。 MongoDB 方案:利用 ObjectId。缺点:不能自增。 《TDDL 在分布式下的SEQUENCE原理》 在数据库中创建 sequence 表,用于记录,当前已被占用的id最大值。 每台客户端主机取一个id区间(比如 1000~2000)缓存在本地,并更新 sequence 表中的id最大值记录。 客户端主机之间取不同的id区间,用完再取,使用乐观锁机制控制并发。 附: * 什么是Snowflake算法 来源: oschina 链接: https://my.oschina.net/u/2339181/blog/1925475

基于数据库构建分布式的ID生成方案

大憨熊 提交于 2019-11-27 19:19:49
在分布式系统中,生成全局唯一ID,有很多种方案,但是在这多种方案中,每种方案都有有缺点,下面我们之针对通过常用数据库来生成分布式ID的方案,其它方法会在其它文中讨论: 1,RDBMS生成ID: 这里我们讨论mysql生成ID。因为MySQL本身可以auto_increment和auto_increment_offset来保证ID自增,很自然地,我们会想到借助这个特性来实现这个功能。 全局ID生成方案里采用了MySQL自增长ID的机制(auto_increment + replace into + MyISAM)。一个生成64位ID方案具体实现是这样的: 先创建单独的数据库(eg:ticket),然后创建一个表: CREATE TABLE Tickets64 ( id bigint(20) unsigned NOT NULL auto_increment, stub char(1) NOT NULL default '', PRIMARY KEY (id), UNIQUE KEY stub (stub) ) ENGINE=MyISAM 表创建之后我们要设置一个初始值,比如100000,执行SELECT * from Tickets64,查询结果就是这样的: 每当我们的应用需要ID的时候就会做如下操作,调用如下存储过程: begin; REPLACE INTO Tickets64

分布式系统唯一ID的生成方案讨论

爷,独闯天下 提交于 2019-11-27 04:37:21
在分布式系统下唯一id问题,就是id咋生成?比如分表分库,因为要是一个表分成多个表之后,每个表的id都是从1开始累加自增长,那是不对的。举个例子,一个表拆分为了2张表,每个表的id都从1开始累加,这个肯定有问题了!你的系统就没办法根据表主键来查询了,比如id = 10这个记录,在两个表里都有!所以此时就需要分布式架构下的全局唯一id生成的方案了,保证每个表内的某个id,全局唯一。全局唯一id主要有以下几种方案。 分布式ID的生成方案 1. UUID 算法的核心思想是结合机器的网卡、当地时间、一个随记数来生成UUID。 优点:本地生成,生成简单,性能好,没有高可用风险 缺点:长度过长,存储冗余,且无序不可读,查询效率低(在数据库里不利于索引树的构建,不适合用作主键) 2. 数据库自增ID 使用数据库的id自增策略,如 MySQL 的 auto_increment。并且可以使用两台数据库分别设置不同步长,生成不重复ID的策略来实现高可用。 优点:数据库生成的ID绝对有序,高可用实现方式简单 缺点:需要独立部署数据库实例,成本高,有性能瓶颈 3. 批量生成ID 一次按需批量生成多个ID,每次生成都需要访问数据库,将数据库修改为最大的ID值,并在内存中记录当前值及最大值。 优点:避免了每次生成ID都要访问数据库并带来压力,提高性能 缺点:属于本地生成策略,存在单点故障

分布式ID生成策略(1)_snowflake算法

只谈情不闲聊 提交于 2019-11-26 17:09:46
  最近在研究分布式ID的生成方法,发现Twitter的snowflake算法挺有意思,因此亲自动手用Java进行了实现。   snowflake算法用64位整数来表示主键,其结构如下图: 1 bit符号位:设计者不喜欢负数主键?方便使用负数标识不正确的ID? 41 bit毫秒时间:2^41 / (365 * 24 * 3600 * 1000) ≈ 69年 10 bit机房ID + 机器ID:最大值为1023 12 bit递增序列:最大值为4095   因为使用机房ID + 机器ID来标识机器,因此可以分散到每台业务机器运行而不会产生重复,不需要集中产生主键,这是这个算法最大的优点。   每秒最多可以生成主键数:4096 * 1000毫秒 = 4096000。以当前机器的配置情况和业务情况,单机每秒400万不重复ID无论如何都已经足够。   虽然算法本身很简单,但分布式集群面临的情况很复杂,编码过程中要考虑的因素有很多。废话不多说,“翠花!上代码!” 1.0 分布式时间发生器 1.1 设计考虑 (1) System.currentTimeMillis()方法每次执行都要进行一次系统内核调用,系统开销较大。对于当前的这个序列号生成器来说,只要保证递增序列从4095归0时获取的时间 比 上次归0时获取的时间大就不会产生重复值,因此使用一个long变量缓存了最近一次时间。 (2)