当前位置: 首页 > article >正文

Go Sonyflake学习与使用

文章目录

      • Sonyflake 特点
      • Sonyflake ID 结构
      • Sonyflake 使用场景
      • Sonyflake 与 Snowflake 的对比
      • Sonyflake 的实现
      • 安装 Sonyflake 库
      • 注意
      • 1. `panic: no point`
        • 解决方法:
      • 2. `panic: memory`
        • 解决方法:
      • 示例代码中的改进

Sonyflake 是一种分布式唯一 ID 生成器,它的设计灵感来自 Twitter 的 Snowflake 算法。Sonyflake 特别适用于分布式系统中生成唯一标识符,具有较高的性能和效率。相比于 Snowflake,Sonyflake 主要改进了 ID 中的时间精度、机器位和序列号位,适合在分布式环境中广泛应用。

Sonyflake 特点

  1. 时间戳

    • Sonyflake 使用 64-bit 的整数来生成唯一的 ID,其中时间戳占据了一部分位数。它的时间起点是 2014-09-01,精度为 10ms。
  2. 机器 ID

    • Sonyflake 支持通过 MAC 地址的后 16 位生成唯一的机器 ID,确保不同机器生成的 ID 唯一性。
  3. 序列号

    • 每台机器上都有一个 16-bit 的序列号,用于在同一个时间戳内生成不同的 ID。如果序列号达到最大值,会等待下一个时间戳。
  4. 高性能

    • Sonyflake 能够在高并发的分布式环境下快速生成 ID,且不会因分布式系统的时间同步问题导致重复 ID。

Sonyflake ID 结构

Sonyflake 生成的 64-bit ID 被划分为不同的字段,各个字段分别表示时间戳、序列号和机器 ID:

  • 39-bit 时间戳:从起点时间(2014-09-01)起以 10ms 为单位的时间戳。
  • 16-bit 序列号:用于在同一时间戳下生成不同的 ID。
  • 8-bit 机器 ID:用来区分不同的机器。

Sonyflake 使用场景

  1. 分布式系统:Sonyflake 非常适合在分布式系统中使用,因为它可以在不依赖中央协调器的情况下生成唯一 ID。

  2. 数据库主键生成:由于生成的 ID 是递增的,它们可以很自然地用于数据库的主键,这有助于提升数据库插入和查询效率。

  3. 日志系统和消息系统:Sonyflake 生成的 ID 能够确保在分布式环境中唯一性,因此在分布式日志系统、消息队列等场景中非常适用。

Sonyflake 与 Snowflake 的对比

特性SonyflakeSnowflake
时间精度10 毫秒1 毫秒
机器 ID8-bit MAC 地址后 16 位生成10-bit 机器 ID
序列号长度16-bit12-bit
时间戳起点2014-09-011970-01-01

Sonyflake 更适合时间粒度要求稍低的系统,特别是对机器标识符要求不同的环境。

Sonyflake 的实现

Sonyflake 常见的实现语言有 Go 语言。以下是一个简单的 Go 示例:

package main

import (
    "fmt"
    "github.com/sony/sonyflake"
)

func main() {
    // 配置 Sonyflake
    settings := sonyflake.Settings{}
    
    // 初始化 Sonyflake
    sf := sonyflake.NewSonyflake(settings)
    
    if sf == nil {
        fmt.Println("Sonyflake initialization failed!")
        return
    }

    // 生成唯一 ID
    id, err := sf.NextID()
    if err != nil {
        fmt.Println("Failed to generate ID:", err)
        return
    }
    
    fmt.Printf("Generated ID: %d\n", id)
}

安装 Sonyflake 库

在 Go 中,可以通过以下方式安装 Sonyflake:

go get github.com/sony/sonyflake

Sonyflake 非常适合在分布式环境中生成唯一标识符,其简单的设计和高效的性能使其在微服务架构中尤为受欢迎。

注意

在使用 Sonyflake 生成唯一 ID 时,如果遇到 panic: no pointpanic: memory 错误,通常是由于以下原因引起的:

1. panic: no point

这个错误提示的主要问题在于 Sonyflake 无法生成新的 ID,原因可能是时间戳没有前进。Sonyflake 依赖系统时钟来生成 ID,如果时钟回退或时间停滞,就可能导致这种情况。可能的原因包括:

  • 系统时钟回退:如果系统时间出现了倒退(例如通过手动设置时间或者 NTP 时间同步导致时钟回调),Sonyflake 会出现时间不一致的问题,无法生成新 ID。

  • 生成 ID 的速率太快:Sonyflake 的时间戳精度是 10ms,如果在同一个 10ms 内生成的 ID 数量超过了序列号的最大值(16-bit,最多 65536 个 ID),它就会进入等待状态,直到时间前进。如果时间没有前进足够多,可能会抛出 no point 错误。

解决方法:
  • 确保系统时间不会回退。可以通过配置系统时间同步服务(如 NTP)以确保系统时间是连续递增的。

  • 降低生成 ID 的速率,或者增加并发机器数量(即增加 machine ID 的数量),避免过多请求集中在同一个时间点。

  • 在程序中引入重试机制:当生成 ID 失败时,可以捕获错误并重试。

2. panic: memory

panic: memory 错误通常与内存分配有关。可能是由于以下原因导致的:

  • 内存不足:如果程序运行在内存有限的环境中,并且分配的资源不够,可能会导致内存溢出错误。

  • 内存泄漏:某些情况下,如果程序中存在内存泄漏,长期运行后可能会导致内存耗尽,从而出现 panic: memory

解决方法:
  • 检查程序的内存使用情况,确保在生成大量 ID 时,内存分配是足够的。

  • 检查程序是否存在内存泄漏,尤其是长时间运行的服务,定期监控内存使用情况并进行优化。

示例代码中的改进

你可以通过以下方式在 Sonyflake 使用中添加错误处理和重试机制,防止 panic

package main

import (
    "fmt"
    "log"
    "time"
    "github.com/sony/sonyflake"
)

func main() {
    // 配置 Sonyflake
    settings := sonyflake.Settings{}

    // 初始化 Sonyflake
    sf := sonyflake.NewSonyflake(settings)
    if sf == nil {
        log.Fatal("Sonyflake initialization failed!")
    }

    for i := 0; i < 10; i++ {
        id, err := generateID(sf)
        if err != nil {
            log.Printf("Failed to generate ID: %v\n", err)
            continue
        }
        fmt.Printf("Generated ID: %d\n", id)
    }
}

// 重试生成 ID 的函数
func generateID(sf *sonyflake.Sonyflake) (uint64, error) {
    for retries := 0; retries < 3; retries++ { // 最多重试 3 次
        id, err := sf.NextID()
        if err != nil {
            if retries < 2 {
                log.Printf("Retrying... (%d/3)\n", retries+1)
                time.Sleep(10 * time.Millisecond) // 等待时间戳前进
                continue
            }
            return 0, err
        }
        return id, nil
    }
    return 0, fmt.Errorf("exceeded maximum retries")
}

在这个示例中,如果 NextID 失败,程序会进行重试,并等待时间戳前进,减少错误的发生概率。

通过这些改进,应该可以有效避免 panic: no pointpanic: memory 的问题。如果问题依然存在,请检查系统时间设置和程序的内存使用情况。


http://www.kler.cn/news/325399.html

相关文章:

  • 新能源汽车充电桩怎么选?
  • Linux基础(二):磁盘分区
  • js替换css主题变量并切换iconfont文件
  • uniapp中h5环境添加console.log输出
  • 2024年7月大众点评沈阳美食店铺基础信息
  • 数据结构和算法之树形结构(4)
  • springframework Ordered接口学习
  • BOE(京东方)携故宫博物院举办2024“照亮成长路”公益项目落地仪式以创新科技赋能教育可持续发展
  • 计算机网络--TCP、UDP抓包分析实验
  • 2024年配置YOLOX运行环境+windows+pycharm24.0.1+GPU
  • [C语言]--自定义类型: 结构体
  • 【C/C++】错题记录(一)
  • pdf页面尺寸裁减
  • uni-app+vue3开发微信小程序使用本地图片渲染不出来报错[渲染层网络层错误]Failed to load local image resource
  • 黑马智数Day2
  • Python pyusb 使用指南【windows+linux】
  • 基于单片机的无线宠物自动喂食系统设计
  • 大数据复习知识点3
  • Python线程终止:如何优雅地结束一场“舞蹈”
  • Mybatis缓存机制(图文并茂!)
  • YOLOv8改进 | 融合篇,YOLOv8主干网络替换为MobileNetV4+CA注意机制+Powerful-IoU损失函数(全网独家首发,实现极限涨点)
  • 力扣刷题之1014.最佳观光组合
  • RK3588主板PCB设计学习(五)
  • CRC循环校验的功能
  • 串行化执行、并行化执行
  • 算法记录——树
  • 学生宿舍管理:Spring Boot技术驱动
  • React 中的无限滚动加载数据实现
  • 探索 JUnit 5:下一代 Java 测试框架
  • Android PopupWindow.showAsDropDown报错:BadTokenException: Unable to add window