WRONGTYPE Operation against a key holding the wrong kind of value

redis报错:

2022/07/20 18:12:32.277 ERROR [0a2cd65e1bef3f0c][task-304318095] o.s.a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void com.test.app.system.bus.listener.DeviceUpwardListener.onApplicationEvent(com.test.app.system.bus.e.DeviceEvent)
redis.clients.jedis.exceptions.JedisDataException: WRONGTYPE Operation against a key holding the wrong kind of value
at redis.clients.jedis.Protocol.processError(Protocol.java:132) ~[jedis-3.1.0.jar!/:na]
at redis.clients.jedis.Protocol.process(Protocol.java:166) ~[jedis-3.1.0.jar!/:na]
at redis.clients.jedis.Protocol.read(Protocol.java:220) ~[jedis-3.1.0.jar!/:na]
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:318) ~[jedis-3.1.0.jar!/:na]
at redis.clients.jedis.Connection.getIntegerReply(Connection.java:260) ~[jedis-3.1.0.jar!/:na]
at redis.clients.jedis.BinaryJedis.hexists(BinaryJedis.java:1034) ~[jedis-3.1.0.jar!/:na]

 

原因是写入redis的key存在两个(多个),但是类型不一样;

如:

jedis.set(“test”,1);

jedis.hset(“test”,”key”1);

此时testkey就存在两种类型且两个,则有可能会报这个错误。

解决方法就是删除重复的键值,建议每一种set方法都加入一个redis方法名作为前缀,这样子就不可能会出现重复的键。

如:

jedis.set(“set:test”,1);

jedis.hset(“hset:test”,”key”1);

形式主义

形式主义,指的是一种只看事物的表象而不加分析其本质的思想方法和工作作风。它违背了内容决定形式、形式为内容服务,内容与形式相统一的科学原理。

形式主义的实质是主观主义、功利主义;其根源是政绩观错位、责任心缺失,用轰轰烈烈的形式代替扎扎实实的落实,用光鲜亮丽的外表掩盖矛盾和问题;具体表现是欺上瞒下,做表面文章,虚多实少,阳奉阴违喊口号多,不折不扣抓落实少。

形式主义(formalism)典型特征是脱离现实生活,强调审美活动的独立性和艺术形式的绝对化,认为是形式决定内容,而不是内容决定形式。

形式主义的产生,有其思想理论基础和社会历史根源,思想理论基础是唯心主义形而上学,社会历史根源是习惯势力和传统文化负面影响。具体到一个单位形式主义产生的根源有二。

一是名利思想。功利主义的私心是滋生形式主义温床。个别领导为了个人和单位出名,显示所谓“成绩”,热衷于搞一些声势大、规模大、影响大的“明星工程”;不考虑单位实际和能力,到处出国考察,每天大吃大喝,浪费国家大量财力、物力;有的眼睛长到头顶上,“只要领导满足,不怕群众骂娘”;有的抓工作只顾眼前,不顾长远,以牺牲单位长远利益为代价换取个人名利。

二是懒惰作风。惰性引发飘浮思想,只管形式,红火,喜欢把功夫下在形式上,只管快,不管效果怎样。有的满足于以文件贯彻文件,以会议贯彻会议,只满足上级指示原本传达,该抓的问题没有及时抓,该解决的问题没有很好地解决。

“形式主义害死人”,基层和群众深恶痛绝。根治形式主义顽症,一定要在思想根源上正本固元,在重点难点上猛药除疴,在责任落实上动真碰硬,在源头治理上防患未然。

《乌合之众:大众心理研究》

如果你对中国的历史有所了解,那你就应该能看出来,勒庞在一百多年前,就已经把这种群体的心理带来的危害告诉了我们,而我们几乎可以简单的套用这个心理状态,清晰的看清我们经历的历史,和历史上的种种悲剧并不是偶然,而是必然。

大家不要觉得这本书开始讲的有点晦涩,就提不起阅读的兴趣,只要读下去,这本书会完完全全给你揭开一个我们面对的、熟悉的社会现象,而且针针见血,字字戳心,由于互联网对文字的限制要高于纸质书,因此我无法一五一十的使用纸质书中的文字,一些敏感词汇只能被其他词汇替代。
首先就是大家要了解一个词汇,就是“无意识”,大家了解这个词汇很关键,无意识和非理性有点相似,但又完全不一样,就像我们走路的过程中,有一些小石子等影响我们走路的小小磕绊情况,我们会不需要特为的躲避,就可以绕过,不影响我们正常的与他人便走边谈和其他的工作,这个绕的来源就是通过人的无意识。

在这本书里,以自我为中心的个体,当进入一个群体之后,理性就会消失,无意识就开始占据你的理性,群体的特征就在你身上显现,你的自我会被淹没,群体意识替代你的自我意识,这会出现什么后果呢?书中给出了一个很让人吃惊的答案。
这个答案就是一旦形成群体时代,除了破坏性作用,群体无法发挥其他作用,我们可以回忆一下我们整个半世纪的历史,是否很熟悉,当然作者写书的那个时代看不到希特勒,看不到我们的历史,但他给出了这个答案,几乎可以用这两段我们熟悉的历史进行验证,因作者生活的时代,仅仅是列举了法国的大革命。
我们如果以小角度看法国,也许是历史的进步,但角度放宽,这同样是一次悲剧,以这种方式同样可以理解我们从五十年到七十年代末这段历史,这还仅仅只是一个表面,更深层的认识,作者进行了细致逻辑的证述,在书中作者明确的指出,当群体形成,群体很容易变成英雄主义群体或者犯罪群体,这两者没有清晰的界限,可以随时变换,来回变换。
在这时,所有的自我个体的思想全部会朝着同一个被引导的方向,他们的自我人格和价值判断完全的丧失,大家还记不记得我们曾经有一个词叫“立场”,如今只要是四十岁以上的人都深刻的认识“立场”的概念,立场就是抹杀自我的价值判断之后,形成的群体意识。

作者在文章中还提出了一个关键的特征,就是在这个群体里,会形成以少数几个人的意识为主导的群体意识,让这种群体意识产生两极化,并且在这种两极化中来回变换,就是我们常说的善良与邪恶,而不是仅仅具有其中的一极,而是两极来回变换,有可能上午是善良的,下午就变成邪恶的,群体已经没有了个体的那种价值判断。
勒庞就此延伸出了,为什么会两极化善恶来回转换的其中一个原因,就是自我个体在群体中的邪恶行为,在群体中会被自己认为不需要承担任何责任,因此价值判断就被淡化,心中就模糊了善恶之分的界限,勒庞还准确的形容这种群体还有着情感丰富的特征,这又和刚才说的善恶模糊完全看似不是一条道吧,然而恰恰就是这样,在读一些我们很多上世纪六七十年代小说里,那种奇怪的社会现象最容易被勒庞的《乌合之众》给解释出来。
书中还说群体有一个奇怪的现象特征,一个群体还会夸大对其英雄的情绪,要求舞台上的英雄具有勇气、美德,但现实生活中,这些却又统统的不存在,这就为什么我们在上世纪六七十年代最愿意树立一些英雄形象的原因吧。

这种对群体心理的重视,就会对民主和个人自由的重视,因为这样是避免群体意识产生的方法,很多灾难都源自这种群体意识的产生。

《自卑与超越》

题记:

没有了解一个人的童年,是不会了解他的现在的。

1、不理智的行为是如何产生的:

在日常生活中,你是否会做出一些自己明知道并不理智的行为?比如沉迷于忙碌的状态中,逃避可能出现的困难,刻意在他人面前表现自己,不想与任何人产生交流,对别人的优秀感到痛苦,无法忍受别人的忽视,想方设法报复他人,或是突然间大发脾气甚至是伤害他人……等等。我们经常会把这些行为归结于各种各样的原因,但其实这些行为的本质,都是源于我们的自卑。

2、自卑是如何产生的:

我们拥有的自卑感,往往源于童年的经历:家庭的贫困、父母的忽视、他人的欺凌、生理的缺陷等等。这是因为当我们还是孩子的时候,对世界的感知能力很强,但是解读能力很差。当我们感受到痛苦的时候,如果没有得到正确的引导,甚至于遭到父母的责骂,我们就很容易将这些痛苦当成自己的过错,把这些痛苦内化成我们自己的一部分,从而形成自卑。

3、我们每个人都有自卑

我们每个人都会有或多或少的自卑感,当我们对面临的问题没有做好恰当的准备或应对,而且认为自己无法解决时,自卑感就出现了。我们常常会因为自卑而感到紧张,不过,正是因为有着自卑感我们才会超越,正是因为超越才得到成长,所以自卑本身并不可怕,可怕的是我们所做的绝大多数行为,其实都是在错误地面对自卑

4、错误面对自卑的方式——寻找优越感:

我们往往会选择两种方式来面对内心的自卑。一种是营造内心的优越感:比如我只要不去努力,就不会暴露自己的能力不足。一种是追求外在的优越感,比如我必须要比别人努力和成功,才可以掩盖自己的能力不足。这两种表现的原因其实是一样的,都是害怕自己能力不足带来的自卑感。同理,当我们害怕受到别人伤害时,既可能通过封闭自己来营造内心的优越感,也可能通过伤害和报复他人来追求外在的优越感。所以,我们绝大多数不理智的行为,本质上都是通过寻找优越感来掩盖自卑的行为。

5、正确面对自卑的第一种方式——认清自卑:

所以,如果想要正确面对我们的自卑,第一种方法是从根本上认清我们的自卑:当我们不认为自己的能力不足时,或者我们不把别人的态度当作伤害时,我们的自卑感自然就迎刃而解了,只要没有自卑感,很多都只是普通的事情而已,这也正是我们为什么很难理解他人痛苦的原因。但当局者迷,如果想要正确认识自己的自卑感,首先要找到自己自卑的根源所在,还要通过学习来掌握认清它的知识,再加上这种自卑感通过长年的积累,已经深深地内化成了我们自身的一部分,所以仅靠我们自己是很难做到的,必须要得到他人的帮助,这也就是正确面对自卑的第二种方法——学会合作。

6、正确面对自卑的第二种方式——学会合作:

虽然我们的自卑感很难避免,但我们还有另外一种面对自卑的方式,那就是——通过与他人的合作来超越自卑。我们每个人其实都是生活在社会中的,职业、同伴和爱人都是我们与社会的连接。如果我们的职业目标是为社会产生价值,与同伴之间更多的是合作关系而不是竞争意识,并且与爱人平等相处、相互关爱的话,我们就能真正跳出寻找优越感的陷阱,从而坦然面对自己的自卑和不足,因为我们将明白人无完人,而我们的不足是可以通过他人的力量弥补的

7、正确的职业目标——价值

一个正确的职业目标,应该是为社会创造价值。如果我们职业目标只是为了活出优越感,那么我们无论做什么都不会满意。如果我们努力的方向不符合社会的需求,那么我们就会陷于忙碌和焦虑之中,而如果我们的行动不考虑他人的利益,我们的行为就会相当不明智,所有的犯罪都是来自于寻找优越感的捷径

8、正确的同伴关系——合作

我们从小受到的教育,培养的都是我们的竞争意识,伤害的却是我们的合作能力。自卑情结往往告诉我们,合作中的成功不属于你,我们总是以竞争意识来面对朋友或同事的关系,但这样只会让我们在寻找优越感的错误上越走越远。相反,如果我们以合作关系来对待我们的同伴,在努力过程中也使别人受益,我们就会更加容易获得他人的合作,也不会发现别人很难被说服。所有的失败者只有一个共同的特点:那就是和他人的合作能力非常差。

9、正确的家庭关系——平等

在一个家庭之中,最好的关系就是平等——夫妻之间平等,父母与子女之间同样平等。夫妻之间应明白双方的所承担的责任只不过是家庭劳动分工的结果,绝不应让自己所做的看起来像是在给予。父母还要帮助孩子去正确的解读在生活中面对的各种各样的问题,让孩子能够感受到自身的能力是可以通过不断训练得到进步的,让孩子感受到来自父母真正的关怀,这样才可以帮孩子正确认识自己,学会合作,学会关爱别人,学会和他人之间建立连接和关系,用父母对待他的方法去对待别人。

10、自卑与超越

我们在心底对价值观和成功的所有评判,最终都建立在合作的基础上,这就是人类最伟大的共同点。心理学就是对合作中缺陷的理解,如果自己和社会、朋友、家人在合作中没有缺陷,那么自己的心理就很健康。所以自卑并不是我们的心理问题,有问题的是当我们感受到自卑的时候去寻找优越感的行为。所以如果想要真正超越自卑,实现自我价值的成长,秘诀就在于这三个词:合作、平等和连接

———————————————–篇二——————————————

1、家庭成员间平等的地位

我们现在常常在提到,要给孩子真正的接纳和爱,讨论如何激发和鼓励孩子的自发成长,然而还有一个重要的问题需要学习:到了孩子从婴幼儿变成儿童时,我们如何不以越位的母爱来宠溺和禁锢孩子

事实上,感情的地位是任何其他经验都无法比拟的。母亲的第一职责就是,当孩子出生时,就让孩子感受到她是可以被依赖的,然后,她会将这种依赖之情扩大,直至它涵盖儿童所接触的环境之中的一切事物。 p.18

更好地完成这一过渡,需要父亲的参与:

当一个母亲成功地和孩子建立联系后,她第二个工作就是将孩子的兴趣引导到父亲身上。

母亲们需要警醒的是:

在问题儿童中,我们发现了各种各样被宠坏的儿童。他们采取一切手段来获得母亲的注意,并拼命排斥与世界的任何联系。

紧接着,阿德勒谈了父亲在家庭中的责任和态度,这在近一个世纪前,无疑的理念领先:

婚姻是一种合作关系,所以两个人都不应该试图驾驭对方。

作为父亲,他必须证明他是妻子的好丈夫、孩子的好父亲、社会的好公民。他必须通过正确的方式应对生活中的三个问题:事业、友情、爱情。他必须以平等的地位与妻子合作,并照顾保护他的家庭。他要记得,在家庭生活中女性的创造性地位是要受到尊重的,他的责任不是贬低妻子的母亲角色,而是和她一起工作。在金钱方面,我们要特别强调,即使父亲是家庭的主要经济来源,财富仍然是家庭共有的,父亲绝对不应该表现出他在施舍,别人在接受。在理想的婚姻生活中,由男人提供主要的家庭经济来源不过是家庭成员之间分工合作的结果。

父亲对孩子的影响非常大。很多孩子一生都把父亲当作自己的偶像,还有一些孩子则将父亲当作自己的敌人。处罚,尤其是体罚,对孩子的伤害是很大的。最正确的教育方式就是友善的方式。

2、判断的形成

但坦率来说,这本书其实不那么容易读懂,显得零散且逻辑脉络不够突出,甚至在通读完整本书,并在尝试读书笔记的时候,仍不能更好地把握什么是「自卑」,什么又是「超越」。书中有这么一段:

当一个人面对一个他解决不了的问题时,他明确表示无法解决这个问题,此时便是自卑心理,此时出现的所有情绪都叫做自卑情绪。由此我们可以看出,眼泪、愤怒、道歉都是自卑心理的表现。自卑心理会让人感到紧张,因此他们会通过优越感来进行补偿,但是他们的目的并不是要解决问题。他们通常把真正要解决的问题放置在一边,通过小事情来寻找优越感。他会限制自己的活动,努力避免导致失败的因素,在困难面前,他们不是表现得勇于进取,解决困难,而是犹豫、彷徨,甚至是退却。

这样的表述似乎不容易答对考试时的名词解释,对吗?

但这本书妙在看似杂而乱,却能成功触碰你的心灵,你感觉一些飘动的成长感受被一击而中,产生了原来如此的感受。

这种感觉很奇妙,举个例子,阿德勒在这本书中重点讨论了三种容易形成错误人生意义的儿童:身体缺陷、被溺爱、被忽视。也许我们在成长过程中都有不同程度或浅或深的体验——比如说对接纳自己身高或容貌的不完美,童年有一位因疼爱自己而特别容易松动底线的长辈,又或者是生活在多子女家庭中、有被忽视的感受。

孩子在童年时期心情压抑,往往就是因为父母过于关心其他兄弟姐妹而忽视了他。

书中紧接着讨论了兄弟姐妹出生次序对成长的影响,这让我产生了强烈的个人生活经验代入感。从生活中来说,有被忽视感觉的可能不是一个孩子——大的觉得小的更受呵护,小的觉得大的拥有更多的自由和权利,中间的觉得自己没有受到足够关注,两头的却羡慕这样不受约束的自由……父母也难做。如果是有一些有公平意识、懂得平衡艺术、并且关心爱护子女的父母,自然是好,然而常有父母双方、或父母中的一方并没有如何教养孩子的意识,也缺乏爱的能力(多是因为他们自己的童年也鲜有得到)。

这样的分析,无疑有助于正在做父母的人,正视子女教育中自己的责任,也让已经成年的人能够了解自己的过往心结。

书中关于「选择性记忆」部分也有很精到的描述:

记忆不是偶然存在的,每个人从自己接收到的、多得不可计数的印象中选择出来进行记忆的,肯定是那些对他所处的情境具有极其重要意义的事件。所以,一个人的记忆是他的生活故事,他会不停地用这个故事安慰自己或警告自己,来使自己集中精力实现自己的目标,并根据过去的经验,让自己以一种成熟的姿态面对未来

记忆的正确性并不是重要的,其最大的价值在于他们代表了一个人的判断

我们看到,经验本身所留下的感受和判断,在童年时期形成,将对一生产生巨大的影响(和束缚)。

3、学校教育的延伸意义

阿德勒非常强调好教师的重要性,认为学校教育是家庭教育的补充,其意义也在于提供比家庭更广阔的领域,让孩子学会与人合作。他对教育目标的立意很高:

我们让孩子接受教育,不仅仅是为了让他找到一份工作或习得一种谋生的技巧,而且让他们在人类的发展历程中贡献自己的力量。

他以成长思维来看待孩子的成长和发展,认为能力不是固定不变的,最差的孩子也有进步的可能,而兴趣点和自信心是可以培养的,「优秀的人具有的不是超出常人的基因,而是不断的努力和丰富的兴趣」。提出思想束缚所能造成的危害,对基因论、先天论、宿命论提出了有力的反驳。

Kafka 日志存储的问题

在进行详解之前,我想先声明一下,本次我们进行讲解说明的是 Kafka 消息存储的信息文件内容,不是所谓的 Kafka 服务器运行产生的日志文件,这一点希望大家清楚。

Kafka 消息是以主题为单位进行归类,各个主题之间是彼此独立的,互不影响。每个主题又可以分为一个或多个分区。每个分区各自存在一个记录消息数据的日志文件。也就是该文要着重关注的内容。我们根据如下的图进行进一步说明:

001

图中,创建了一个 demo-topic 主题,其存在 7 个 Parition,对应的每个 Parition 下存在一个 [Topic-Parition] 命名的消息日志文件。在理想情况下,数据流量分摊到各个 Parition 中,实现了负载均衡的效果。在分区日志文件中,你会发现很多类型的文件,比如:.index、.timestamp、.log、.snapshot 等,其中,文件名一致的文件集合就称为 LogSement。我们先留有这样的一个整体的日志结构概念,接下来我们一一的进行详细的说明其中的设计。

LogSegment

我们已经知道分区日志文件中包含很多的 LogSegment ,Kafka 日志追加是顺序写入的,LogSegment 可以减小日志文件的大小,进行日志删除的时候和数据查找的时候可以快速定位。同时,ActiveLogSegment 也就是活跃的日志分段拥有文件拥有写入权限,其余的 LogSegment 只有只读的权限。

日志文件存在多种后缀文件,重点需要关注 .index、.timestamp、.log 三种类型。其他的日志类型功能作用,请查询下面图表:

类别 作用
.index 偏移量索引文件
.timestamp 时间戳索引文件
.log 日志文件
.snaphot 快照文件
.deleted
.cleaned 日志清理时临时文件
.swap Log Compaction 之后的临时文件
Leader-epoch-checkpoint

每个 LogSegment 都有一个基准偏移量,用来表示当前 LogSegment 中第一条消息的 offset。偏移量是一个 64 位的长整形数,固定是20位数字,长度未达到,用 0 进行填补,索引文件和日志文件都由该作为文件名命名规则(00000000000000000000.index、00000000000000000000.timestamp、00000000000000000000.log)。特别说明一下,如果日志文件名为 00000000000000000121.log ,则当前日志文件的一条数据偏移量就是 121,偏移量是从 0 开始的。

如果想要查看相应文件内容可以通过 kafka-run-class.sh 脚本查看 .log :

/data/kafka/bin/kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.log

002

2.0 中可以使用 kafka-dump-log.sh 查 看.index 文件

/data/kafka/bin/kafka-dump-log.sh --files ./00000000000000000000.index

日志与索引文件

配置项 默认值 说明
log.index.interval.bytes 4096 (4K) 增加索引项字节间隔密度,会影响索引文件中的区间密度和查询效率
log.segment.bytes 1073741824 (1G) 日志文件最大值
log.roll.ms 当前日志分段中消息的最大时间戳与当前系统的时间戳的差值允许的最大范围,毫秒维度
log.roll.hours 168 (7天) 当前日志分段中消息的最大时间戳与当前系统的时间戳的差值允许的最大范围,小时维度
log.index.size.max.bytes 10485760 (10MB) 触发偏移量索引文件或时间戳索引文件分段字节限额

偏移量索引文件用于记录消息偏移量与物理地址之间的映射关系。时间戳索引文件则根据时间戳查找对应的偏移量。

Kafka 中的索引文件是以稀疏索引的方式构造消息的索引,他并不保证每一个消息在索引文件中都有对应的索引项。每当写入一定量的消息时,偏移量索引文件和时间戳索引文件分别增加一个偏移量索引项和时间戳索引项,通过修改 log.index.interval.bytes 的值,改变索引项的密度。

切分文件

从上文中可知,日志文件和索引文件都会存在多个文件,组成多个 SegmentLog,那么其切分的规则是怎样的呢?

当满足如下几个条件中的其中之一,就会触发文件的切分:

  1. 当前日志分段文件的大小超过了 broker 端参数 log.segment.bytes 配置的值。log.segment.bytes 参数的默认值为 1073741824,即 1GB。
  2. 当前日志分段中消息的最大时间戳与当前系统的时间戳的差值大于 log.roll.ms 或 log.roll.hours 参数配置的值。如果同时配置了 log.roll.ms 和 log.roll.hours 参数,那么 log.roll.ms 的优先级高。默认情况下,只配置了 log.roll.hours 参数,其值为168,即 7 天。
  3. 偏移量索引文件或时间戳索引文件的大小达到 broker 端参数 log.index.size.max.bytes 配置的值。log.index.size.max.bytes 的默认值为 10485760,即 10MB。
  4. 追加的消息的偏移量与当前日志分段的偏移量之间的差值大于 Integer.MAX_VALUE,即要追加的消息的偏移量不能转变为相对偏移量。
为什么是 Integer.MAX_VALUE ?

在偏移量索引文件中,每个索引项共占用 8 个字节,并分为两部分。相对偏移量和物理地址。

相对偏移量:表示消息相对与基准偏移量的偏移量,占 4 个字节

物理地址:消息在日志分段文件中对应的物理位置,也占 4 个字节

4 个字节刚好对应 Integer.MAX_VALUE ,如果大于 Integer.MAX_VALUE ,则不能用 4 个字节进行表示了。

索引文件切分过程

索引文件会根据 log.index.size.max.bytes 值进行预先分配空间,即文件创建的时候就是最大值,当真正的进行索引文件切分的时候,才会将其裁剪到实际数据大小的文件。这一点是跟日志文件有所区别的地方。其意义降低了代码逻辑的复杂性。

查找消息

offset 查询

偏移量索引由相对偏移量和物理地址组成。

003

可以通过如下命令解析.index 文件

/data/kafka/bin/kafka-dump-log.sh --files ./00000000000000000000.index
offset:0 position:0
offset:20 position:320
offset:43 position:1220

注意:offset 与 position 没有直接关系哦,由于存在数据删除和日志清理。

004

e.g. 如何查看 偏移量为 23 的消息?

Kafka 中存在一个 ConcurrentSkipListMap 来保存在每个日志分段,通过跳跃表方式,定位到在 00000000000000000000.index ,通过二分法在偏移量索引文件中找到不大于 23 的最大索引项,即 offset 20 那栏,然后从日志分段文件中的物理位置为320 开始顺序查找偏移量为 23 的消息。

时间戳方式查询

在上文已经有所提及,通过时间戳方式进行查找消息,需要通过查找时间戳索引和偏移量索引两个文件。

时间戳索引索引格式

005

006+

 

e.g. 查找时间戳为 1557554753430 开始的消息?

  • 将 1557554753430 和每个日志分段中最大时间戳 largestTimeStamp 逐一对比,直到找到不小于 1557554753430 所对应的日志分段。日志分段中的 largestTimeStamp 的计算是先查询该日志分段所对应时间戳索引文件,找到最后一条索引项,若最后一条索引项的时间戳字段值大于 0 ,则取该值,否则去该日志分段的最近修改时间。
  • 找到相应日志分段之后,使用二分法进行定位,与偏移量索引方式类似,找到不大于 1557554753430 最大索引项,也就是 [1557554753420 430]。
  • 拿着偏移量为 430 到偏移量索引文件中使用二分法找到不大于 430 最大索引项,即 [20,320] 。
  • 日志文件中从 320 的物理位置开始查找不小于 1557554753430 数据。

注意:timestamp文件中的 offset 与 index 文件中的 relativeOffset 不是一一对应的哦。因为数据的写入是各自追加。

在偏移量索引文件中,索引数据都是顺序记录 offset ,但时间戳索引文件中每个追加的索引时间戳必须大于之前追加的索引项,否则不予追加。在 Kafka 0.11.0.0 以后,消息信息中存在若干的时间戳信息。如果 broker 端参数 log.message.timestamp.type 设置为 LogAppendTIme ,那么时间戳必定能保持单调增长。反之如果是 CreateTime 则无法保证顺序。

日志清理

日志清理,不是日志删除哦,这还是有所区别的,日志删除会在下文进行说明。

Kafka 提供两种日志清理策略:

日志删除:按照一定的删除策略,将不满足条件的数据进行数据删除

日志压缩:针对每个消息的 Key 进行整合,对于有相同 Key 的不同 Value 值,只保留最后一个版本。

Kafka 提供 log.cleanup.policy 参数进行相应配置,默认值:delete,还可以选择 compact。

是否支持针对具体的 Topic 进行配置?

答案是肯定的,主题级别的配置项是 cleanup.policy 。

日志删除

配置 默认值 说明
log.retention.check.interval.ms 300000 (5分钟) 检测频率
log.retention.hours 168 (7天) 日志保留时间小时
log.retention.minutes 日志保留时间分钟
log.retention.ms 日志保留时间毫秒
file.delete.delay.ms 60000 (1分钟) 延迟执行删除时间
log.retention.bytes -1 无穷大 运行保留日志文件最大值
log.retention.bytes 1073741824 (1G) 日志文件最大值

Kafka 会周期性根据相应规则进行日志数据删除,保留策略有 3 种:基于时间的保留策略、基于日志大小的保留策略和基于日志其实偏移量的保留策略。

基于时间

日志删除任务会根据 log.retention.hours/log.retention.minutes/log.retention.ms 设定日志保留的时间节点。如果超过该设定值,就需要进行删除。默认是 7 天,log.retention.ms 优先级最高。

如何查找日志分段文件中已经过去的数据呢?

Kafka 依据日志分段中最大的时间戳进行定位,首先要查询该日志分段所对应的时间戳索引文件,查找时间戳索引文件中最后一条索引项,若最后一条索引项的时间戳字段值大于 0,则取该值,否则取最近修改时间。

为什么不直接选最近修改时间呢?

因为日志文件可以有意无意的被修改,并不能真实的反应日志分段的最大时间信息。

删除过程
  1. 从日志对象中所维护日志分段的跳跃表中移除待删除的日志分段,保证没有线程对这些日志分段进行读取操作。
  2. 这些日志分段所有文件添加 上 .delete 后缀。
  3. 交由一个以 "delete-file" 命名的延迟任务来删除这些 .delete 为后缀的文件。延迟执行时间可以通过 file.delete.delay.ms 进行设置

如果活跃的日志分段中也存在需要删除的数据时?

Kafka 会先切分出一个新的日志分段作为活跃日志分段,然后执行删除操作。

基于日志大小

日志删除任务会检查当前日志的大小是否超过设定值。设定项为 log.retention.bytes ,单个日志分段的大小由 log.regment.bytes 进行设定。

删除过程

  1. 计算需要被删除的日志总大小 (当前日志文件大小-retention值)。
  2. 从日志文件第一个 LogSegment 开始查找可删除的日志分段的文件集合。
  3. 执行删除。

基于日志起始偏移量

基于日志起始偏移量的保留策略的判断依据是某日志分段的下一个日志分段的起始偏移量是否大于等于日志文件的起始偏移量,若是,则可以删除此日志分段。

注意:日志文件的起始偏移量并不一定等于第一个日志分段的基准偏移量,存在数据删除,可能与之相等的那条数据已经被删除了。

007

删除过程
  • 从头开始遍历每一个日志分段,日志分段 1 的下一个日志分段的起始偏移量为 11,小于 logStartOffset,将 日志分段 1 加入到删除队列中
  • 日志分段 2 的下一个日志分段的起始偏移量为 23,小于 logStartOffset,将 日志分段 2 加入到删除队列中
  • 日志分段 3 的下一个日志分段的起始偏移量为 30,大于 logStartOffset,则不进行删除。
123110
 
Copyright © 2008-2021 lanxinbase.com Rights Reserved. | 粤ICP备14086738号-3 |