分布式自增序列id的实现(二) ---分布式序号生成器

本文在分布式自增序列的实现(一) ---分布式序号生成器基础上成文,因此直接上解决办法,省去问题的讨论。请先阅读分布式自增序列的实现(一) ---分布式序号生成器

上一篇我们提到使用zookeeper的持久化序列node来自动生成分布式序列id,本文将讨论使用redis的INCR功能实现分布式自增序列的实现。redis是单线程的,它能保证生成的序列是不重复的。

Redis incr功能介绍

官方文档https://redis.io/commands/incr
Increments the number stored at key by one. If the key does not exist, it is set to 0 before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64 bit signed integers.

Note: this is a string operation because Redis does not have a dedicated integer type. The string stored at the key is interpreted as a base-10 64 bit signed integer to execute the operation.

Redis stores integers in their integer representation, so for string values that actually hold an integer, there is no overhead for storing the string representation of the integer.

The counter pattern is the most obvious thing you can do with Redis atomic increment operations.
可以看到最大的序列是64bit的有符号的整型, 最大值是2的63次方-1, 也就是9,223,372,036,854,775,807,基本上绝大部分项目够用了。从0开始。特别是文档中的这句,"incr可以用作计数器模式,它是原子自增操作。"

具体代码实现

我直接使用的spring-data-redis,程序基于springboot。完整代码在这里,欢迎加星,fork。 本程序启动时会自动连接redis, 请先配置好自己的redis服务器ip和端口等信息.

本示例代码使用了RedisAtomicLong ,请参考官方文档https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/support/atomic/RedisAtomicLong.html 我们主要使用addAndGet方法。

服务层代码

package com.yq.service.impl;

import com.yq.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Simple to Introduction
 * className: RedisServiceImpl
 *
 * @author EricYang
 * @version 2018/8/4 23:00
 */
@Service
@Slf4j
public class RedisServiceImpl implements RedisService {

    @Autowired
    private StringRedisTemplate template;

    @Autowired
    RedisAtomicLong redisAtomicLong;

    private static final String LONG_KEY = "yqLong";

    @Bean
    public RedisAtomicLong getRedisAtomicLong() {
        RedisAtomicLong counter = new RedisAtomicLong(LONG_KEY, template.getConnectionFactory());
        return counter;
    }

    @Override
    public String get(String key) {
        ValueOperations<String, String> ops = this.template.opsForValue();
        return ops.get(key);
    }

    @Override
    public void set(String key, String value) {
        ValueOperations<String, String> ops = this.template.opsForValue();
        ops.set(key, value);
    }

    @Override
    public String getHash(String key, String hashKey) {
        HashOperations<String, String, String> hashOps = this.template.opsForHash();
        return hashOps.get(key, hashKey);
    }

    @Override
    public void setHash(String key, String hashKey, String value) {
        HashOperations<String, String, String> hashOps = this.template.opsForHash();
        hashOps.put(key, hashKey, value);
    }

    @Override
    public long getRedisSequence() {
        long sequence = 0L;
        try {
            if (redisAtomicLong.get() == 0) {
                redisAtomicLong.getAndSet(0L);
            }
            sequence = redisAtomicLong.incrementAndGet();
        } catch (Exception ex) {
            log.error("Failed to get sequence.", ex);
        }
        return sequence;
    }
}

controller层代码, 供其他服务调用

@RestController
@RequestMapping("/cache")
public class RedisController {
    private Logger logger = LoggerFactory.getLogger(RedisController.class);

   @Autowired
   RedisService redisService;

    @ApiOperation(value = "获取sequence")
    @GetMapping(value = "/sequence", produces = "application/json;charset=UTF-8")
    public long getSequence() {
        long value = redisService.getRedisSequence();
        return value;
    }
    。。。

效果截图

getSequence.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,448评论 0 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 1 Redis介绍1.1 什么是NoSql为了解决高并发、高可扩展、高可用、大数据存储问题而产生的数据库解决方...
    克鲁德李阅读 5,274评论 0 36
  • 文/赖佳秀 冬姐姐穿着雪白的衣服悄悄地走了,春妹妹来了,她给故乡穿上了五颜六色的新衣,大地美起来了,香起来...
    我爱无花果阅读 617评论 0 0
  • 无意间看到张小娴写的:女人需要三样东西 1.男人 2.爱情 3.安全感 我终于知道所有的痛苦的症结...
    竹筠益阅读 331评论 0 1