kafka中的offset

深度解析 Kafka 中的 Offset 管理与最佳实践 Offset 是 Kafka 中标识消息在分区内位置的一个唯一标识符。每个消息都有一个对应的 Offset 值,用于表示消息在分区中的相对位置。Offset 的管理对于确保消息处理的顺序性和容错性非常重要。在深度解析Kafka中的Offset管理与最佳实践后,深入探讨了Offset的基本概念、管理机制和各种调优策略。了解了消费者组与Offset的紧密关系,学习了Offset的提交、存储和重置等重要操作,使我们能够更好地保障消息传递的顺序性和一致性。 阅读详情

官方文档定义:kafka是一个分布式、可分区、多副本的日志系统。

kafka术语:

  • massage: kafka中最基本的传递对象,有固定格式。
  • topic: 一类消息,如page view,click行为等。
  • producer: 产生信息的主体,可以是服务器日志信息等。
  • consumer: 消费producer产生话题消息的主体。
  • broker: 消息处理结点,多个broker组成kafka集群。
  • partition: topic的物理分组,每个partition都是一个有序队列。
  • segment: 多个大小相等的段组成了一个partition。
  • offset: 一个连续的用于定位被追加到分区的每一个消息的序列号,最大值为64位的long大小,19位数字字符长度。

对于一个消息系统而言,追踪客户消费了什么,也即消息消费状态是每个消息系统必须提供的关键功能之一。
系统可以提供的几种可能消息传递保障有3种:

  • At most once 消息至多会被发送一次,但如果产生网络延迟等原因消息就会有丢失。
  • At least once 消息至少会被发送一次,上面既然有消息会丢失,那么给它加一个消息确认机制即可解决,但是消息确认阶段也还会出现同样问题,这样消息就有可能被发送两次。
  • Exactly once 消息只会被发送一次,这是我们想要的效果。

那么kafka是怎么解决的呢?
kafka的解决方案:

  • broker将数据流划分为一组互相独立的分区。这些分区的语义由producer定义,由producer指定每条消息属于哪个分区。一个分区内的消息以到达broker的时间为准排序,将来按此顺序将消息发送给consumer。这样一来,就用不着为每一条消息保存一条元数据(比如标记该消息已使用)了,我们只需要为producer、topic、partition的每种组合记录一个“最高水位标记”(high water mark)即可。我们把这个最高水位标记称作偏移量offset。

topic、partition、segment、offset的关系:

  • partition、segment、offset都是为topic服务的,每个topic可以分为多个partition,一个partition相当于一个大目录,每个partition下面有多个大小相等的segment文件,这个segment是由message组成的,而每一个的segment不一定由大小相等的message组成。segment大小及生命周期在server.properties文件中配置。offset用于定位位于段里的唯一消息。

topic、partition、segment、offset的关系

接下来弄清楚segment具体细节之后再说offset:

  • segment由index和data文件组成,两个文件成对出现,分别存储索引和数据。
  • segment文件命名规则:对于所有的partition来说,segment名称从0开始,之后的每一个segment名称为上一个segment文件最后一条消息的offset值。

那么对于分区中的一个offset例如等于345552怎么去查找相应的message呢?

  • 先找到该message所在的segment文件,通过二分查找的方式寻找小于等于345552的offset,假如叫S的segment符合要求,如果S等于345552则S上一个segment的最后一个message即为所求;如果S小于345552则依次遍历当前segment即可找到。

实际上offset的存储采用了稀疏索引,这样对于稠密索引来说节省了存储空间,但代价是查找费点时间。
稀疏索引与稠密索引

关于Kafka 的消息日志Offset 的了解 之前在做Kafka 整合Storm的时候,因为对Kafka 不是很熟,考虑过这样的一个场景问题,针对一个Topic,Kafka消息日志中有个offset信息来标注消息的位置,Storm每次从kafka 消费数据,都是通过zookeeper存储的数据offset,来判断需要获取消息在消息日志里的起始位置。 而Kafla 有个参数log.retention.hours会根据设定的小时,来清理日志文件 阅读详情

相关推荐

Kafka offset管理

Kafka offset管理 消费者在消费的过程中需要记录自己消费了多少数据,即消费 Offset。Kafka Offset 是Consumer Position,与 Broker 和 Producer 都无关。每个 Consumer Group、每个 Topic 的每个Partition 都有各自的 Offset,如下图所示。 通常由如下几种 Kafka Offset 的管理方式: S...

擦玻璃的程序员专栏 6218

深入解析Kafka的offset管理

Kafka中的每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序号,用于partition唯一标识一条消息。 Offset记录着下一条将要发送给Consumer的消息的序号。 Offset从语义上来看拥有两种:Current Offset 和 Committed Offset。 Current Offset Current Offset保存在Consumer客户端中,它表示Consumer希望收到的下一

zjjcchina的博客 1万+

flink消费kafka管理offset

通过自定义kafkaconsumer的反序列方式是可以拿到kafka message的所有信息的,包括topic partition offset等。 自行设置偏移量保存位置 这里采用了zookeeper作为保存的地址,就是实时更新偏移量属性。再job挂掉后重新拉取偏移量保存下来 就能一次消费啦,但真正做到一次消费必须和业务场景结合来做,比如事务。 废话不多说啦,我本地实现了一个例子 <dependency> <groupId&g..

longlovefilm的博客 2920

kafka —— offset篇

KAFKA offset提交方式 三种 1、自动提交方式 “enable.auto.commit”, “true” 是否自动提交 “auto.commit.interval.ms”, “5000” 间隔多久ms提交 2、手动提交 —— 同步 consumer.commitSync(); 3、手动提交 —— 异步 consumer.commitAsync(); 3种提交方式优缺点 1、自动提交 优点:不用自己管理offset 缺点:可能会出现数据重复 原因: 调用poll()方法时将offset提交,所以如果

idream 4683

Flink消费Kafka数据时指定offset的五种方式

下面是Flink读取Kafka数据的代码,其中就有五种读取offset的方式,并配置相应的介绍 final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.enableCheckpointing(5000); env.setStreamTimeCharacteri...

gxd520的专栏 1万+

Kafka中的auto-offset-reset配置

如果kafka服务器记录有消费者消费到的offset,那么消费者会从该offset开始消费。如果Kafka中没有初始偏移量,或者当前偏移量在服务器上不再存在(例如,因为该数据已被删除),那么这时 auto.offset.reset 配置项就会起作用。

北辰 6718

Kafka offset 最大值是多少,offset 会溢出吗?Kafka consumer offset max value?

Question I was googling and reading Kafka documentation but I couldn’t find out the max value of a consumer offset and whether there is offset wraparound after max value. I understand offset is an Int64 value so max value is 0xFFFFFFFFFFFFFFFF. If there is

寒泉 6万+

Kafka(七) offset机制

Offset 是 Kafka 中标识消息在分区内位置的一个唯一标识符。每个消息都有一个对应的 Offset 值,用于表示消息在分区中的相对位置。Offset 的管理对于确保消息处理的顺序性和容错性非常重要。就是消费的位置偏移量offset 是 Kafka 为每条消息分配的一个唯一的编号,它表示消息在分区中的顺序位置。offset 是从 0 开始的,每当有新的消息写入分区时,offset 就会加 1。offset 是不可变的,即使消息被删除或过期,offset 也不会改变或重用。

技术博客 1908

kafka offset入门理解

offset是什么? 一个数字,记录了消费位置 offset有什么用? 消费者在消费数据时,发生宕机后,再次重新启动后,消费的数据需要从宕机位置开始读取 如果从头读取,有一部分消息一定出现了重复消费 如果从宕机时的消费位置读取,就不会出现重复消费 因此kafka设计了offset可以用于处理这种情况 如何维护offset的数值? 有两种方式, 自动提交,设置enable.auto.commit=true,更新的频率根据参数【auto.commit.interval.ms】来定。这种方式也被称为【at

鸭梨的博客 6402

Kafka 自动 Offset 提交详解

在分布式流处理系统中,数据的一致性和准确性至关重要。以 Kafka 为例,它是一种流行的消息队列系统,常用于构建高吞吐量的数据管道和流应用程序。在处理 Kafka 中的消息时,消费者需要跟踪其消费到的消息位置,即 Offset。然而,手动管理 Offset 不仅繁琐,而且容易出错。以下是一个场景问题,用以引出 Kafka 自动 Offset 提交这一知识点的介绍。场景问题:在一个基于 Kafka 的实时数据分析系统中,一个消费者组负责处理来自多个主题的数据。

AIHacksCash的博客 962

【Latex】【附安装文件】Miktex和TexStudio的安装与配置

这代表“构建并运行”,一般来说,我们只需要点这个按钮来运行Latex代码。保存一下代码文件,再运行一次,PDF文件会出现在与代码文件相同的文件夹下。安装完成后,你可能会跳转到一个页面中,你看到这个页面就意味着安装成功了。其实不需要你敲,你只要将下面的代码复制粘贴到你刚刚的文件中即可。成功安装MikTex后,我们需要进行更新,减少后续使用的麻烦。如果懂得将安装路径设置在你想要的盘中,你可以自己设置。双击上文的.exe文件后,你会看到如下画面。如果不懂,为避免不必要的麻烦,请直接点击“

未来就在脚下。 1万+

在Docker环境中重置Kafka Offset

在Docker环境中重置Kafka Offset

qq_45080738的博客 1342

Matlab激活失败?手把手教你解决License checkout failed问题(附详细截图)

本文针对Matlab激活后出现“License checkout failed”错误的常见问题,提供了详细的解决方案。核心在于精准定位并正确填写Windows系统用户名,而非计算机名或账户全名。文章通过分步截图和命令指引,手把手教你使用`whoami`命令获取正确信息,并重新运行激活程序,从根本上解决因用户名填写错误导致的许可检查失败问题。

weixin_29062823的博客 576

flink kafka offset配置

一:flink kafka offset配置 1. setStartFromGroupOffsets(默认的): example: Map specificStartOffsets = new HashMap<>(); specificStartOffsets.put(new KafkaTopicPartition("myTopic", 0), 23L); specificStartOffsets.put(new KafkaTopicPartition("myTopic", 1), 31L);

奈文摩尔ST 1663

STLink驱动安装全攻略:从卸载到Keil配置的完整避坑指南

本文提供了STLink驱动安装与Keil环境配置的完整避坑指南。详细讲解了从驱动卸载、重装到Keil调试器设置的每一步,并针对常见的设备无法识别、连接不稳定等问题给出了深度解决方案,帮助开发者快速搭建稳定的STM32开发环境。

weixin_29182481的博客 425

永磁同步电机高效标定技术:从理论到实践的全面解析

本文全面解析永磁同步电机高效标定技术,从MTPA标定、弱磁区优化到初始角校准,详细介绍了理论原理和实战技巧。针对新能源汽车应用场景,提供标定系统集成要点和AI辅助优化方案,帮助工程师提升电机性能标定效率与精度。

weixin_28452161的博客 503

清理offset_重置kafka的offset

如果你在使用Kafka来分发消息,在数据处理的过程中可能会出现处理程序出异常或者是其它的错误,会造成数据丢失或不一致。这个时候你也许会想要通过kafka把数据从新处理一遍,我们知道kafka默认会在磁盘上保存到7天的数据,你只需要把kafka的某个topic的consumer的offset设置为某个值或者是最小值,就可以使该consumer从你设置的那个点开始消费。查询topic的offset的范...

weixin_39914732的博客 697

手把手教你:在openEuler 22.03上离线搞定OpenSSH 9.8升级(CentOS 7.9通用)

本文详细介绍了在openEuler 22.03和CentOS 7.9系统上离线升级OpenSSH 9.8的完整流程,包括准备工作、离线包获取、安装步骤、服务管理及回滚方案。特别针对无外网环境的企业服务器,提供安全可靠的离线升级解决方案,帮助运维人员有效提升系统安全性。

weixin_30682415的博客 192

Kafka的offset自定义存储实现

一、什么是Offset 在kafka中,每一条消息都有一个与之对应的序列号,这个序列号就是offset,表示消息的偏移量。 特点: 偏移量从0开始递增 topic中的每个分区维护自己的一个offset 二、Offset存储位置 每个消费者本地内存中会存储自己当前消费消息的offset,以便下次消费消息从offset+1开始消费。 此外,消费者每次消费完消息后还要将offset提价到kafka集群,kafka集群会将offset保存到kafka本地。 对应的就是一条group_

xdkb159的博客 1668

Linux系统故障排查思路实践教程(上)

本文主要介绍了Linux系统日志分析与常见故障排查的实用方法。首先从系统日志的分类及其涉及的日志文件进行说明;其次详细讲解了忘记用户密码的解决方案;接着对系统无法启动问题,提供了异常断电后修复文件系统、/etc/fstab文件丢失恢复等常见故障的处理方案。最后介绍了文件系统只读错误的排查思路和修复方法,包括磁盘空间检查、文件系统修复等实用技巧。全文提供了大量具体命令和操作流程,为Linux系统维护人员提供了实用的故障处理指南。

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 330

[Dify实战] 解决 Dify 导入 DSL 文件时报 “DSL 版本差异” 的兼容性问题

摘要:本文针对Dify开发者在导入.dsl文件时遇到的版本警告提示问题,分析其根源在于DSL文件与当前系统版本不一致。解决方案是通过导出当前Dify应用的DSL文件查看版本号,手动修改待导入文件的version字段以匹配。文章详细说明了操作步骤,并给出使用专业编辑器、避免修改其他字段等实用建议,帮助开发者规避版本不兼容问题,提升多模态AI应用开发效率。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 961

kafka—offset偏移量

1.offset基本概念 2.offset的提交 3.消费者优化

weixin_44604159的博客 2922

(一)激光线扫描-三维成像原理

激光线扫描是一种使用激光作为光源,通过特定的扫描设备(如光学镜头、电机驱动的镜头或电子扫描设备)将激光束引导到目标表面,并按照预定的路径进行扫描的技术。这种技术通常用于测量、检测、打印、切割等多种应用中。

FlyWine的博客 3630

kafka 调整offset

背景说明 kafka客户端程序异常导致消费积压,再恢复时遗留的历史消息太多,而追赶到最新消息需费时太久,无法贴合业务使用场景; 和业务部门协商确定: 可以丢弃中间未消费的数据,将指定offset(指定消费组消费topic)调整到最新值; 【kafka-消费堆积】 告警时间: 2020.04.02 10:52:22 主机名称: slhd1.op-paas.kafka001 [主题] : heartbeat_sync_pdd_game 消费组: heart-consumer 触发器: >20000

qstater的博客 5017

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Kafka如何记录Offset

消费位移的存储位置消费位移存储在Kafka内部的一个特殊Topic中:__consumer_offsets,这个Topic是Kafka自动创建和管理的:位移在__consumer_offsets中的存储格式__consumer_offsetsTopic中消息的Key-Value结构:Key: [消费者组名, Topic名, 分区号]Value: [位移值, 元数据, 时间戳]例如消费者查找位移的过程Broker挂掉重启后的恢复过程Broker重启对消费位移的影响。

weixin_37862824的博客 730

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

kafka offset 机制

kafka消息处理类:MessageAndOffset case class MessageAndOffset(message: Message, offset: Long) { /**   * Compute the offset of the next message in the log   */  def nextOffset: Long = offset + 1 } ...

stuliper的专栏 4745

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

上一篇: 稀疏索引与稠密索引
下一篇: ITEXT-插入水印(itext-pdfa-5.5.6.jar)
sand_clock
博客等级 码龄11年 66粉丝 89原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值