海量数据处理商用短链接生成器平台 - 6

第十二章 海量数据下的分库分表技术栈讲解

第1集 大话业界常见数据库分库分表中间件介绍

简介: 大话业界常见分库分表中间件介绍

  • 业界常见分库分表中间件
    • Cobar(已经被淘汰没使用了)
    • TDDL
      • 淘宝根据自己的业务特点开发了 TDDL (Taobao Distributed Data Layer)
      • 基于JDBC规范,没有server,以client-jar的形式存在,引入项目即可使用
      • 开源功能比较少,阿里内部使用为主
    • Mycat
      • 地址 http://www.mycat.org.cn/
      • Java语言编写的MySQL数据库网络协议的开源中间件,前身 Cobar
      • 遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理
      • 是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成一个 MySQL 数据库
      • 和ShardingShere下的Sharding-Proxy作用类似,需要单独部署

在这里插入图片描述

ShardingSphere 下的Sharding-JDBC

  • 地址:https://shardingsphere.apache.org/
  • Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈
    • 它由 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar 3个独立产品组合
  • Sharding-JDBC
    • 基于jdbc驱动,不用额外的proxy,支持任意实现 JDBC 规范的数据库
    • 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖
    • 可理解为加强版的 JDBC 驱动,兼容 JDBC 和各类 ORM 框架

在这里插入图片描述

  • 面试官最喜欢问的,是Mycat和ShardingJdbc区别
    • 两者设计理念相同,主流程都是SQL解析–>SQL路由–>SQL改写–>结果归并
    • sharding-jdbc
      • 基于jdbc驱动,不用额外的proxy,在本地应用层重写Jdbc原生的方法,实现数据库分片形式
      • 是基于 JDBC 接口的扩展,是以 jar 包的形式提供轻量级服务的,性能高
      • 代码有侵入性
    • Mycat
      • 是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成一个 MySQL 数据库
      • 客户端所有的jdbc请求都必须要先交给MyCat,再有MyCat转发到具体的真实服务器
      • 缺点是效率偏低,中间包装了一层
      • 代码无侵入性
第2集 分库分表中间件Apache ShardingSphere急速认知

简介: 分库分表中间件Apache ShardingSphere急速认知

  • 什么是ShardingSphere

    • 已于2020年4月16日成为 Apache 软件基金会的顶级项目
    • 是一套开源的分布式数据库解决方案组成的生态圈,定位为 Database Plus
    • 它由 JDBC、Proxy 和 Sidecar这 3 款既能够独立部署,又支持混合部署配合使用的产品组成
  • 三大构成(下面图片素材来源 sharding-sphere官网)

    • ShardingSphere-Sidecar(规划中,简单知道就行)

      • 定位为 Kubernetes 的云原生数据库代理,以 Sidecar(边车) 的形式代理所有对数据库的访问
      • 通过无中心、零侵入的方案提供与数据库交互的啮合层,即 Database Mesh,又可称数据库网格
    • ShardingSphere-JDBC

      • 它使用客户端直连数据库,以 jar 包形式提供服务
      • 无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架
      • 适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis,或直接使用 JDBC
      • 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等;
      • 支持任意实现 JDBC 规范的数据库,目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何可使用 JDBC 访问的数据库
      • 采用无中心化架构,与应用程序共享资源,适用于 Java 开发的高性能的轻量级 OLTP 应用

在这里插入图片描述

  • ShardingSphere-Proxy
    • 数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持
    • 向应用程序完全透明,可直接当做 MySQL/PostgreSQL
    • 它可以使用任何兼容 MySQL/PostgreSQL 协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat 等)操作数据

在这里插入图片描述

第3集 分库分表和Sharding-Jdbc常见概念术语讲解

简介: 分库分表和Sharding-Jdbc常见概念术语讲解

  • 站着统一水平线上,沟通无障碍,统一下专业术语

  • 数据节点Node

    • 数据分片的最小单元,由数据源名称和数据表组成
    • 比如:ds_0.product_order_0
  • 真实表

    • 在分片的数据库中真实存在的物理表
    • 比如订单表 product_order_0、product_order_1、product_order_2
  • 逻辑表

    • 水平拆分的数据库(表)的相同逻辑和数据结构表的总称
    • 比如订单表 product_order_0、product_order_1、product_order_2,逻辑表就是product_order
  • 绑定表

    • 指分片规则一致的主表和子表
    • 比如product_order表和product_order_item表,均按照order_id分片,则此两张表互为绑定表关系
    • 绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升

在这里插入图片描述

  • 广播表
    • 指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致
    • 适用于数据量不大且需要与海量数据的表进行关联查询的场景
    • 例如:字典表、配置表
第4集 分库分表和Sharding-Jdbc常见分片算法讲解

简介: 分库分表和Sharding-Jdbc常见分片算法讲解

  • 数据库表分片(水平库、表)

    • 包含分片键和分片策略
  • 分片键 (PartitionKey)

    • 用于分片的数据库字段,是将数据库(表)水平拆分的关键字段
    • 比如prouduct_order订单表,根据订单号 out_trade_no做哈希取模,则out_trade_no是分片键
    • 除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片
  • 分片策略

    • 行表达式分片策略 InlineShardingStrategy

      • 只支持【单分片键】使用Groovy的表达式,提供对SQL语句中的 =和IN 的分片操作支持

      • 可以通过简单的配置使用,无需自定义分片算法,从而避免繁琐的Java代码开发

      • prouduct_order_$->{user_id % 8}` 表示订单表根据user_id模8,而分成8张表,表名称为`prouduct_order_0`到`prouduct_order_7
        
    • 标准分片策略StandardShardingStrategy

      • 只支持【单分片键】,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法
      • PreciseShardingAlgorithm 精准分片 是必选的,用于处理=和IN的分片
      • RangeShardingAlgorithm 范围分配 是可选的,用于处理BETWEEN AND分片
      • 如果不配置RangeShardingAlgorithm,如果SQL中用了BETWEEN AND语法,则将按照全库路由处理,性能下降
    • 复合分片策略ComplexShardingStrategy

      • 支持【多分片键】,多分片键之间的关系复杂,由开发者自己实现,提供最大的灵活度
      • 提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持
      • prouduct_order_0_0、prouduct_order_0_1、prouduct_order_1_0、prouduct_order_1_1
    • Hint分片策略HintShardingStrategy

      • 这种分片策略无需配置分片健,分片健值也不再从 SQL中解析,外部手动指定分片健或分片库,让 SQL在指定的分库、分表中执行

      • 用于处理使用Hint行分片的场景,通过Hint而非SQL解析的方式分片的策略

      • Hint策略会绕过SQL解析的,对于这些比较复杂的需要分片的查询,Hint分片策略性能可能会更好

    • 不分片策略 NoneShardingStrategy

      • 不分片的策略。
  • 自己实现分片策略的优缺点

    • 优点:可以根据分片策略代码里面自己拼装 真实的数据库、真实的表,灵活控制分片规则
    • 缺点:增加了编码,不规范的sql容易造成全库表扫描,部分sql语法支持不友好

第十三章 流量包模块-海量数据下的分库分表《青铜玩法》

第1集 账号微服务-流量包模块水平分表需求讲解和开发

简介: 账号微服务-流量包模块水平分表需求讲解和开发

  • 需求

    • 未来2年,短链平台累计5百万用户
      • 付费流量包记录:一个用户10条/年,总量就是5千万条
      • 单表不超过1千万数据,需要分5张表
      • 进一步延伸,进行水平分表,比如 2张表、4张表、8张表、16张表
    • 流量包traffic表数据太多,选取可用流量包 会影响性能,需要降低单表数据量,进行水平分表
    • 分表数量:线上分8张表,本地分2张表即可
    • 分片key: account_no,查询维度都是根据account_no进行查询
    • 分片策略:行表达式分片策略 InlineShardingStrategy
  • 新建表

    • traffic_0
    • traffic_1
    CREATE TABLE `traffic_0` (
      `id` bigint unsigned NOT NULL AUTO_INCREMENT,
      `day_limit` int DEFAULT NULL COMMENT '每天限制多少条,短链',
      `day_used` int DEFAULT NULL COMMENT '当天用了多少条,短链',
      `total_limit` int DEFAULT NULL COMMENT '总次数,活码才用',
      `account_no` bigint DEFAULT NULL COMMENT '账号',
      `out_trade_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '订单号',
      `level` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '产品层级:FIRST青铜、SECOND黄金、THIRD钻石',
      `expired_date` date DEFAULT NULL COMMENT '过期日期',
      `plugin_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '插件类型',
      `product_id` bigint DEFAULT NULL COMMENT '商品主键',
      `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
      `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_trade_no` (`out_trade_no`,`account_no`) USING BTREE,
      KEY `idx_account_no` (`account_no`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
    
  • 配置

    • 加入 sharding-jdbc依赖包,account项目注释下面的依赖排查
              <exclusions>
                    <exclusion>
                        <groupId>org.apache.shardingsphere</groupId>
                        <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
                    </exclusion>
                </exclusions>
    
    • 配置文件 (注释之前jdbc单库配置)
    # 数据源 ds0 第一个数据库
      shardingsphere:
        datasource:
          ds0:
            connectionTimeoutMilliseconds: 30000
            driver-class-name: com.mysql.cj.jdbc.Driver
            idleTimeoutMilliseconds: 60000
            jdbc-url: jdbc:mysql://120.79.150.146:3306/dcloud_account?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
            maintenanceIntervalMilliseconds: 30000
            maxLifetimeMilliseconds: 1800000
            maxPoolSize: 50
            minPoolSize: 50
            password: xdclass.net168
            type: com.zaxxer.hikari.HikariDataSource
            username: root
          names: ds0
        props:
        # 打印执行的数据库以及语句
          sql:
            show: true
    
    
        sharding:
          tables:
            traffic:
    # 指定traffic表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
              actual-data-nodes: ds0.traffic_$->{0..1}
    
第2集 账号微服务-流量包模块水平分表策略配置和测试实战

简介: 账号微服务-流量包模块水平分表策略配置和测试实战

  • 水平分表策略配置
# 水平分表策略+行表达式分片
          table-strategy:
            inline:
              algorithm-expression: traffic_$->{account_no % 2}
              sharding-column: account_no
  • 单元测试
  @Autowired
    private TrafficMapper trafficMapper;


    @Test
    public  void testSaveTraffic(){


        Random random = new Random();
        for(int i=0;i<3;i++) {
            TrafficDO trafficDO = new TrafficDO();
            trafficDO.setAccountNo(Long.valueOf(random.nextInt(1000)));
            trafficMapper.insert(trafficDO);
        }
    }


  • 问题
    • 主键id重复
第3集 分库分表暴露的问题-ID冲突和分布式id生成介绍

简介: 分库分表暴露的问题-ID冲突和分布式id生成

  • 单库下一般使用Mysql自增ID, 但是分库分表后,会造成不同分片上的数据表主键会重复。

  • 需求

    • 性能强劲
    • 全局唯一
    • 防止恶意用户根据id的规则来获取数据
  • 业界常用ID解决方案

    • 数据库自增ID

      • 利用自增id, 设置不同的自增步长,auto_increment_offset、auto-increment-increment
      DB1: 单数
      //从1开始、每次加2
      
      
      DB2: 偶数
      //从2开始,每次加2
      
      
      
      • 缺点
        • 依靠数据库系统的功能实现,但是未来扩容麻烦
        • 主从切换时的不一致可能会导致重复发号
        • 性能瓶颈存在单台sql上
    • UUID

      • 性能非常高,没有网络消耗
      • 缺点
        • 无序的字符串,不具备趋势自增特性
        • UUID太长,不易于存储,浪费存储空间,很多场景不适用
    • Redis发号器

      • 利用Redis的INCR和INCRBY来实现,原子操作,线程安全,性能比Mysql强劲
      • 缺点
        • 需要占用网络资源,增加系统复杂度
    • Snowflake雪花算法

      • twitter 开源的分布式 ID 生成算法,代码实现简单、不占用宽带、数据迁移不受影响
      • 生成的 id 中包含有时间戳,所以生成的 id 按照时间递增
      • 部署了多台服务器,需要保证系统时间一样,机器编号不一样
      • 缺点
        • 依赖系统时钟(多台服务器时间一定要一样)
第4集 带你彻底掌握分布式 ID 生成算法Snowflake原理

简介: 小D-带你彻底掌握分布式 ID 生成算法Snowflake原理

  • 什么是雪花算法Snowflake

    • twitter用scala语言编写的高效生成唯一ID的算法

    • 优点

      • 生成的ID不重复
      • 算法性能高
      • 基于时间戳,基本保证有序递增
  • 计算机的基础知识回顾

    • bit与byte

      • bit(位):电脑中存储的最小单位,可以存储二进制中的0或1
      • byte(字节):一个byte由8个bit组成
    • 常规64位系统里面java数据类型存储字节大小

      • int:4 个字节
      • short:2 个字节
      • long:8 个字节
      • byte:1 个字节
      • float:4 个字节
      • double:8 个字节
      • char:2 个字节
    • 科普:数据类型在不同位数机器的平台下长度不同(怼面试官的严谨性)

      • 16位平台 int 2个字节16位
      • 32位平台 int 4个字节32位
      • 64位平台 int 4个字节32位
  • 雪花算法生成的数字,long类,所以就是8个byte,64bit

    • 表示的值 -9223372036854775808(-2的63次方) ~ 9223372036854775807(2的63次方-1)
    • 生成的唯一值用于数据库主键,不能是负数,所以值为0~9223372036854775807(2的63次方-1)

在这里插入图片描述

第5集 分布式ID生成器Snowflake里面的坑你是否知道

简介: 分布式ID生成器Snowflake里面的坑你是否知道

  • 分布式ID生成器需求

    • 性能强劲
    • 全局唯一不能重复
    • 防止恶意用户根据id的规则来获取数据
  • 全局唯一不能重复-坑

    • 坑一

      • 分布式部署就需要分配不同的workId, 如果workId相同,可能会导致生成的id相同
    • 坑二:

      • 分布式情况下,需要保证各个系统时间一致,如果服务器的时钟回拨,就会导致生成的 id 重复
  • 配置实操

    • spring.shardingsphere.sharding.tables.traffic.key-generator.props.worker.id=1
      
    • 方式一

      • 订单id使用MybatisPlus的配置,TrafficDO类配置

        @TableId(value = "id", type = IdType.ASSIGN_ID)
        默认实现类为DefaultIdentifierGenerator雪花算法
        
    • 方式二

      • 使用Sharding-Jdbc配置文件,注释DO类里面的id分配策略
      #id生成策略
                key-generator:
                  column: id
                  props:
                    worker:
                      id: 0
                  #id生成策略
                  type: SNOWFLAKE
      
第6集 分布式ID生成器Snowflake自定义wrokId实战

简介: 分布式ID生成器Snowflake自定义wrokId实战

  • 进阶:动态指定sharding jdbc 的雪花算法中的属性work.id属性
    • 使用sharding-jdbc中的使用IP后几位来做workId, 但在某些情况下会出现生成重复ID的情况
      • 解决办法时
        • 在启动时给每个服务分配不同的workId, 引入redis/zk都行,缺点就是多了依赖
        • 启动程序的时候,通过JVM参数去控制,覆盖变量
@Configuration
public class SnowFlakeWordIdConfig {


    /**
     * 动态指定sharding jdbc 的雪花算法中的属性work.id属性
     * 通过调用System.setProperty()的方式实现,可用容器的 id 或者机器标识位
     * workId最大值 1L << 100,就是1024,即 0<= workId < 1024
     * {@link SnowflakeShardingKeyGenerator#getWorkerId()}
     *
     */
    static {
        try {
            InetAddress ip4 = Inet4Address.getLocalHost();
            String addressIp = ip4.getHostAddress();
            System.setProperty("workerId", (Math.abs(addressIp.hashCode())%1024)+"");
        } catch (UnknownHostException e) {
            throw new BizException(BizCodeEnum.OPS_NETWORK_ADDRESS_ERROR);
        }
    }
}

在这里插入图片描述

  • 配置
#id生成策略
          key-generator:
            column: id
            props:
              worker:
                id: ${workerId}
            #id生成策略
            type: SNOWFLAKE
第7集 shardingjdbc-Snowflake时间回拨问题解决和封装ID生成器

简介: shardingjdbc-Snowflake时间回拨问题解决和封装ID生成器

  • shardingjdbc-Snowflake里面解决时间回拨问题

在这里插入图片描述

  • 需求
    • 用户注册-生成的account_no需要是long类型,且全局唯一
  • 利用Sharding-Jdbc封装id生成器
public class IDUtil {


    private static SnowflakeShardingKeyGenerator shardingKeyGenerator = new SnowflakeShardingKeyGenerator();


    /**
     * 雪花算法生成器,配置workId,避免重复
     *
     * 10进制 654334919987691526
     * 64位 0000100100010100101010100010010010010110000000000000000000000110
     *
     * {@link SnowFlakeWordIdConfig}
     *
     * @return
     */
    public static Comparable<?> geneSnowFlakeID(){
        return shardingKeyGenerator.generateKey();
    }
}
  • 修改注册时账号生成策略

第十四章 短链服务-业务需求和短链码解决方案讲解

第1集 短链服务介绍和应用场景讲解

简介: 短链服务介绍和应用场景讲解

  • 什么是短链服务

在这里插入图片描述

  • 业务背景:为啥需要短链

    • 公司电商产品推广、业务活动页、广告落地页 缺少实时【数据反馈和渠道效果分析】
    • 老项目业务推广【没人维护,无法做埋点】需要统计效果
      • 例子 https://tongji.baidu.com/web/demo/overview/index?siteId=16847648
    • APP和营销活动发送营销短信链接过长,【浪费短信发送费用】
    • 国内【反垄断后】微信、抖音、淘宝 流量互通,很多知识付费公司需要做 私域流量、社群运营
    • 可以对外做产品输出,实现商业化能力增加公司营收
    • 积累终端数据和人群数据,为公司未来产品人群做策略助力
    • 更多。。。。
  • 短链组成

    • 协议://短链域名/短链码
  • 最简单的方式

    • 一个短链编码,去数据库select * from table where code =XXX,返回给用户就行
第2集 需求出发-带你详细一个短链的生命周期

简介: 需求出发带你详细一个短链的生命周期

  • 创建者和访问者

在这里插入图片描述

创建者

  • 流量包管理
    • 免费流量包
    • 付费流量包

在这里插入图片描述

分组管理

  • 新增分组
  • 删除分组
  • 修改分组
  • 查看分组下的短链

在这里插入图片描述

在这里插入图片描述

短链管理

  • 创建短链
    • 目标地址
    • 短链标题
    • 短链域名
    • 所属分组
    • 有效期

在这里插入图片描述

      • 删除短链
      • 修改短链
      • 查看短链
        • 访问PV、UV
        • 地域分布
        • 时间分布
        • 来源分布
  • 访问者
    • 访问短链
    • 跳转目标站点
第3集 短链服务生成短链URL的问题你能想到多少

简介: 短链URL生成服务里面的问题你能想到多少

  • 短链码如何生成

在这里插入图片描述

需要解决的问题(自己是技术Leader,能否想到这些问题,并解决。做架构设计之前,要想清楚)

  • 问题一:长链的关系和短链的关系
    • 一对一?
    • 一对多?
    • 多对多?
  • 问题二:前端访问短链是如何跳转到对应的页面的?
  • 问题三:短链码是如何生成的
    • 知道几种方式?
  • 问题四:SaaS类型业务,数据量有多大,是否要分库分表
  • 问题五:如果分库分表,PartitionKey是哪个?使用怎样的策略
  • 问题六:如果分库分表,访问短链怎么知道具体是哪个库哪个表?
  • 问题七:如果分库分表,怎么查看某个账号创建的全部短链?
第4集 短链服务问题解决方案讲解-业务关系+跳转问题

简介: 短链服务问题解决方案讲解-业务关系+跳转问题

  • 问题一:长链的关系和短链的关系是一对一还是一对多?

    • 一个长链,在不同情况下,生成的短网址应该不一样,才不会造成冲突
    • 多渠道推广下,也可以区分统计不同渠道的效果质量
    • 所以是 一个短链接只能对应一个长链接,当然一个长链接可以对应多个短链接
  • 问题二:前端访问短链是如何跳转到对应的页面的?

    • 服务端转发

      • 由服务器端进行的页面跳转,刚学Servlet时, 从OneServlet中转发到TwoServlet
      • 地址栏不发生变化,显示的是上一个页面的地址
      • 请求次数:只有1次请求
      • 转发只能在同一个应用的组件之间进行,不可以转发给其他应用的地址
       request.getRequestDispatcher("/two").forward(request, response); 
      

在这里插入图片描述

页面的跳转-重定向

  • 由浏览器端进行的页面跳转

在这里插入图片描述

  • 重定向涉及到3xx状态码,访问跳转是301还是302,301和302代表啥意思?
    • 301 是永久重定向
      • 会被浏览器硬缓存,第一次会经过短链服务,后续再访问直接从浏览器缓存中获取目标地址
    • 302 是临时重定向
      • 不会被浏览器硬缓存,每次都是会访问短链服务
    • 短地址一经生成就不会变化,所以用 301 是同时对服务器压力也会有一定减少
    • 但是如果使用了 301,无法统计到短地址被点击的次数
    • 所以选择302虽然会增加服务器压力,但是有很多数据可以获取进行分析
    • 选择使用302,这个也可以对违规推广的链接进行实时封禁
第5集 短链服务问题解决方案讲解-短链码生成解决方案《上》

简介: 短链服务问题解决方案讲解-短链码生成解决方案《上》

  • 问题三:短链码如何是如何生成的
  • 短链码特点
    • 生成性能强劲
    • 碰撞概率低
      • 避免重复
      • 恶意猜测
    • 业务规则安全

在这里插入图片描述

方式

  • 自增ID

    • 利用插入数据库,利用数据库自增id
    • 把自增id转成62进制作为短链码
    • 短链码的长度不固定,随着 id 变大,短链码长度也增长
    • 可以指定从某个长度开始增长,到百亿、千亿数量
    • 转换工具:https://tool.lu/hexconvert/
    • 是否存在重复: 不重复
    • 但短链码是有序的递增,存在【业务数据安全】问题
    • MD5内容压缩

      • 长链接做md5加密
      43E08496,9E5CF455,E6D2D2B3,3407A6D2
      
      • 加密串查询是否已经生成过短链接
        • 如果已经存在,则拼接时间戳再MD5加密,插入数据库
        • 如果不存在则把长链接、长链接加密串插入数据库
      • 取MD5后 最后1 个 8 位字符串作为短链码
      • 是否存在重复: 存在碰撞(重复)可能
      • 是有损压缩算法,数据量超大情况碰撞概念越大
        • 比如 老王的女友有300多个,每再多1个,再同一天生日的概率越大,就更加复杂
第6集 【重要】敏感数据+自增ID暴露的商业秘密

简介: 敏感数据讲解+自增ID暴露的商业秘密

  • 什么是数据脱敏

    • 也叫数据的去隐私化,在给定脱敏规则和策略的情况下,对敏感数据比如 手机号身份证 等信息,进行转换或者修改的一种技术手段,防止敏感数据直接在不可靠的环境下使用和泄露、撞库等

    • 技术分两类

      • 静态数据脱敏
        • 将生产数据导出,进行对外发送或者给开发、测试人员等
      • 动态数据脱敏
        • 程序直接连接生产数据的场景,如运维人员在运维的工作中直接连接生产数据库进行运维
        • 客服人员在生产中通过后台查询的个人信息
  • 数据库业务规则安全:自增ID暴露的商业秘密

    • 背景

      作为后端开发人员肯定离不开数据库设计,尽管你知道数据安全、接口安全、网络安全,但你也很大可能不小心暴露的公司的核心机密。 
      
      
      【做空上市公司的股票】如果你有炒股,那你知道如果这个数据库设计漏洞被他人知道,就可以做空一个上司公司的股票的不?
      【摧毁对手的利器】如果一个公司在是靠业务数据来说话的,如果被他人知道,在核心的时间点,被披露出来,那融资可能凉凉,企业可能面临倒闭。
      
    • 在某天一个竞争对手 老王 做竞品调研的时候,注册了你公司的应用

      【暴露了总用户量】
      
      
      通过业务接口抓包分析(假定数据没做加密或者加密被破解了),被他发现了自增id这个事情,他好几个号注
      
      
      册了,编号都是一百多万,每次id都是自增1, 用户量最多100多万,就此暴雷了。
      
      
      经过有经验的人知道不能对外暴露id这个事情,但是总有关联的业务,或者其他不知道的人员开发了对应
      
      
      的功能,比如 订单表、记录表、收藏表或者其他和user_id有关联的,只要他操作业务,接口有返回user_id,就容易出问题了。
      
      【暴露了每日拉新数据】
      如果是用户自增id,老王 肯定不单停留这里这么简单,假如他想看这个产品每日新增的用户有多少。
      
      
      毕竟拉新这个指标是很多公司都离不开的,比如通过投放广告、买量业务等等去获取新用户。
      
      
      老王想看下这个公司每天新增用户量大不大,他就今天注册一个看id多少,明天再注册一个看id多少;
      
      
      通过一段时间内去统计每天递增的值,老王就可以推断出平台新增用户大概是多少了,公司的拉新能力如何。
      
      【暴露了平台商品数量-订单数量】
      
      
      同样的思路,去爬取电商平台的商品,爬取平台最大的商品id, 第二天再次爬取,持续一段时间。就可以可以推断出新品发布数量。
      
      
      同样的思路,去抓取订单接口,看最大id是多少, 第二天再次爬取,持续一段时间。就可以推断出这个公司的每天订单量有多大。
      
  • 结语:

    • 看到这里,你觉得你公司的自增id敢不敢乱用,是不是不但只是技术那么简单了。
    • 合格的架构,不单止某个技术厉害,更要考虑和业务-商业上的结合。
    • 正常的业务表,会用自增id,但是也会加个业务id,比如下面的
CREATE TABLE `USER` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `biz_id` varchar(64) DEFAULT NULL COMMENT '业务id',
  `name` varchar(128) DEFAULT NULL COMMENT '昵称',
  `pwd` varchar(124) DEFAULT NULL COMMENT '密码',
  `head_img` varchar(524) DEFAULT NULL COMMENT '头像',
  `phone` varchar(64) DEFAULT '' COMMENT '手机号',
  `login_type` int(10) DEFAULT NULL COMMENT '登录类型',
  `email` varchar(128) DEFAULT NULL COMMENT '邮箱',
  `sex` tinyint(2) DEFAULT '1' COMMENT '0表示女,1表示男',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `roles` varchar(11) DEFAULT NULL COMMENT '1,2,3,数字权限,逗号分隔',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=100000 DEFAULT CHARSET=utf8;




增加了 biz_id,这个就是业务id, 如果有关联,则用 biz_id进行关联并返回,这个可以是varchar类型,long雪花算法.


其实最靠谱的就是,不要把有业务规则的id暴露给用户,不止id字段,类似的敏感字段都是
第7集 短链服务问题解决方案讲解-短链码生成解决方案《下》

简介: 短链URL服务问题解决方案讲解-短链码生成解决方案《下》

  • 哈希算法:将一个元素映射成另一个元素

    • 加密哈希,如SHA256、MD5(上集讲了)

    • 非加密哈希,如MurMurHash,CRC32

  • MurMurHash

    Murmur哈希是一种非加密散列函数,适用于一般的基于散列的查找。
    它在2008年由Austin Appleby创建,在Github上托管,名为“SMHasher” 的测试套件。 
    它也存在许多变种,所有这些变种都已经被公开。 
    该名称来自两个基本操作,乘法(MU)和旋转(R)--来自百科
    
    • 是一种【非加密型】哈希函数且【随机分布】特征表现更良好

    • 由于是非加密的哈希函数,性能会比MD5强

    • 再很多地方都用到比如Guava、Jedis、HBase、Lucence等

    • 存在两个版本

      • MurmurHash2(产生32位或64位值)
      • MurmurHash3(产生32位或128位值)
    • 数据量

      • MurmurHash的 32 bit 能表示的最大值近 43 亿的10进制
        • 满足多数业务,如果接近43亿则冲突概率大
      • 产品目标【超理想情况】
      首年日活用户: 10万
      
      
      首年日新增短链数据:10*50 = 500万
      
      
      年新增短链数:500* 365= 18.2亿 
      
      
      年新增用户数:50/1年
      
      
      年营收目标: 10万付费用户 * 客单价200= 2千万
      
      
      新增短链:50/用户每日
      
      • MurMurHash得到的数值是10进制,一般会转化为62进制进行缩短
        • 例子
          • 10进制:1813342104
          • 转62进制:1YIB7i
          • https://tool.lu/hexconvert/
      • 常规短链码是6~8位数字+大小写字母组合
      0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
      
      
      6 位 62 进制数可表示 568 亿个短链(62的6次方,每位都有62个可能,如果扩大位数到7位,则可以支持3万5200亿)
      
      • MurmurHash的 32 bit 满足多数业务 43亿
        • 拼接上库-表位则可以表示更多数据(后续会讲分库分表的,库表位)
        • 7位则可以到到 43亿 * 62 = 2666亿
        • 8位则可以到到 2666亿 * 62 = 1.65万亿条数据
        • 结合短链过期数据归档,理论上满足未来全部需求了
      • 数据库存储
        • 单表1千万 * 62个库 * 62表 = 384亿数据

h3(产生32位或128位值)

  • 数据量

    • MurmurHash的 32 bit 能表示的最大值近 43 亿的10进制
      • 满足多数业务,如果接近43亿则冲突概率大
    • 产品目标【超理想情况】
    首年日活用户: 10万
    
    
    首年日新增短链数据:10*50 = 500万
    
    
    年新增短链数:500* 365= 18.2亿 
    
    
    年新增用户数:50/1年
    
    
    年营收目标: 10万付费用户 * 客单价200= 2千万
    
    
    新增短链:50/用户每日
    
    • MurMurHash得到的数值是10进制,一般会转化为62进制进行缩短
      • 例子
        • 10进制:1813342104
        • 转62进制:1YIB7i
        • https://tool.lu/hexconvert/
    • 常规短链码是6~8位数字+大小写字母组合
    0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
    
    
    6 位 62 进制数可表示 568 亿个短链(62的6次方,每位都有62个可能,如果扩大位数到7位,则可以支持3万5200亿)
    
    • MurmurHash的 32 bit 满足多数业务 43亿
      • 拼接上库-表位则可以表示更多数据(后续会讲分库分表的,库表位)
      • 7位则可以到到 43亿 * 62 = 2666亿
      • 8位则可以到到 2666亿 * 62 = 1.65万亿条数据
      • 结合短链过期数据归档,理论上满足未来全部需求了
    • 数据库存储
      • 单表1千万 * 62个库 * 62表 = 384亿数据
  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从零开始学习人工智能

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

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

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

打赏作者

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

抵扣说明:

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

余额充值