业务系统到底需要什么样的ID生成器

ID 生成器在微博我们一直叫发号器,微博就是用这样的号来存储,而我微博里讨论的时候也都是以发号器为标签。它的主要目的确如平常大家理解的“为一个分布式系统的数据object产生一个唯一的标识”,但其实在一个真实的系统里可能也可以承担更多的作用。概括起来主要有以下几点:

  1. 唯一性
  2. 时间相关
  3. 粗略有序
  4. 可反解
  5. 可制造

下面我会分别讲每个作用后面的考虑和权衡,也会对比介绍一下业界已知的几种 ID 设计。

  1. 要唯一性,是否需要全局唯一?

    说起全局唯一,通常大家都会在想到发号器服务,分布式的通常需要更大空间,中心式的则需要在一个合适的地方在会聚。这就可能涉及到锁,而锁意味着成本和性能的下降。所以当前的系统是否需要全局的唯一性,就是一个需要考虑的问题。

    比如在通讯系统里,聊天消息可能就未必需要全局,因为一条消息只是某一个人发出,系统只要保证一个人维度的唯一性即可。本质上而言,这里利用了用户 ID 的唯一性,因为唯一性是可以依赖的,通常我们设计系统也都是基于类似的性质,比如后面降到的使用时间唯一性的方式。

  2. 用时间来做什么?千万年太久,只争朝夕?

    前面说到唯一性可以依赖,我们需要选择的是依赖什么。通常的做法可以选择数据库自增,这在很多数据库里都是可以满足ACID 的操作。但是用数据库有个缺点,就是数据库有性能问题,在多机房情况下也很难处理。当然,你可以通过调整自增的步长来设计,但对于一个发号器而言,操作和维护都略重了。

    而时间是天然唯一的,因此也是很多设计的选择。但对于一个8Byte的 ID 而言,时间并没有那么多。你如果精确到秒级别,三十年都要使用30bit,到毫秒级则要再增加10bit,你也只剩下20bit 可以做其他事情了。之所以在8Byte 上捣鼓,因为8Byte 是一个Long,不管在处理器和编译器还是语言层面,都是可以更好地被处理。

    然而三十年够么?对于一个人来说,可能不够,但对一个系统而言,可能足够。我们经常开玩笑,互联网里能活三十年的系统有多少呢?三十年过去,你的系统可能都被重写 N 遍了。这样的信心同样来自于摩尔定律,三十年后,计算性能早就提高了上千倍,到时候更多Byte 都不会是问题了。

  3. 粗略有多粗略,秒还是毫秒?

  4.  余下全文请点击这里查看 

### 使用 DeepSeek 进行 SQL 生成模型训练 DeepSeek 是一种强大的工具,能够用于多种自然语言处理任务,其中包括将自然语言查询转换成结构化查询语言(SQL)[^2]。对于想要利用 DeepSeek 来创建一个可以自动生成 SQL 的系统的开发者来说,理解其工作原理和具体实现方法至关重要。 #### 准备数据集 为了使机器学习算法有效地学习如何把人类可读的语言转化为数据库命令,准备高质量的数据集是第一步。这通常意味着收集大量的配对样本——每一对都由一条描述所需操作的人类语言指令及其对应的正确 SQL 查询组成。这些数据应该覆盖尽可能多的不同场景,以便让模型学会应对各种可能的情况。 #### 配置环境并安装依赖库 在开始之前,确保已经设置了适当的工作环境,并且安装了必要的 Python 库来支持项目开发: ```bash pip install deepseek-transformers datasets transformers torch ``` 这段代码会下载并安装 `deepseek-transformers` 和其他所需的包,它们提供了构建和微调预训练大模型的基础功能[^1]。 #### 加载预训练模型与分词器 接着加载预先训练好的 DeepSeek 模型实例以及配套使用的 BPE(Byte Pair Encoding) 或 WordPiece 分词组件: ```python from transformers import AutoModelForSeq2SeqLM, AutoTokenizer model_name_or_path = 'path_to_deepseek_model' # 替换成实际路径或Hugging Face上的模型ID tokenizer = AutoTokenizer.from_pretrained(model_name_or_path) model = AutoModelForSeq2SeqLM.from_pretrained(model_name_or_path) ``` 上述脚本初始化了一个特定版本的 DeepSeek 模型对象 (`model`) 和相应的文本编码解码机制(`tokenizer`),使得后续可以直接输入未经加工的文字串给它处理。 #### 定义训练参数及优化配置 定义超参数如批量大小(batch size),轮次(epoch number),初始学习率(learning rate)等,并指定所选用的优化器(optimizer): ```python training_args = { "output_dir": "./results", "num_train_epochs": 3, "per_device_train_batch_size": 8, "save_steps": 500, "logging_steps": 100, } optimizer = torch.optim.AdamW(params=model.parameters(), lr=5e-5) ``` 这里设定了几个重要的选项,比如输出目录(output directory),迭代次数(number of epochs),每次传递给网络前向传播函数时的最大条目数(per device train batch size)等等。同时选择了 AdamW 作为默认更新权重的方式之一。 #### 开始训练过程 最后一步就是编写循环体来进行真正的训练活动,在此期间不断调整内部参数直至收敛至满意状态为止: ```python for epoch in range(training_args["num_train_epochs"]): model.train() for step, (input_ids, attention_mask, labels) in enumerate(train_dataloader): outputs = model(input_ids=input_ids, attention_mask=attention_mask, labels=labels) loss = outputs.loss loss.backward() optimizer.step() optimizer.zero_grad() if (step + 1) % training_args['logging_steps'] == 0: print(f"Epoch {epoch}, Step {step}: Loss={loss.item()}") # Save checkpoint after each epoch model.save_pretrained(os.path.join(training_args["output_dir"], f"checkpoint-{epoch}")) ``` 通过这种方式,可以根据自己的需求定制整个流程中的每一个环节,从而获得更加贴合业务特点的结果。当完成一轮完整的周期之后,记得保存当前的状态点(checkpoint),方便以后继续改进或者部署上线服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值