022-2345 2937
185 2247 0110
business@forenose.com
QQ:2779623375
用户QQ群3:606835039
用户QQ群4:795287153
订阅号
服务号
客服微信:qianxiu0106
数据资讯
数据学院
数据百科
查询限制条数 | 语法: SELECT TOP number|percent column_name(s) FROM table_name 例子; SELECT TOP 3 * FROM Customers; | 语法: SELECT * FROM table_name LIMIT number; 例子: SELECT * FROM ratings ORDER BY category LIMIT 5; 数据类型转换 | 创建临时表 语法:CONVERT(data_type(length), expression, style) 说明: data_type:【必要】支持的数据类型 bigint, int, smallint, tinyint, bit, decimal, numeric, money, smallmoney, float, real, datetime, smalldatetime, char, varchar, text, nchar, nvarchar, ntext, binary, varbinary, image expression:【必要】转换成其他数据类型的值 length:【可选】数据类型的长度 例子: SELECT CONVERT(varchar, 25.65); | 表名必须以“#“开头 CREATE TABLE #MaleStudents ( name VARCHAR(50), age int, gender VARCHAR (50) ) 语法:CONVERT(expr, type) 等价于 CAST(expr AS type) 说明: expr:转换成其他数据类型的值 type:数据类型 BINARY[(N)] CHAR[(N)] [charset_info] DATE DATETIME DECIMAL[(M[,D])] JSON NCHAR[(N)] SIGNED [INTEGER] TIME UNSIGNED [INTEGER] 例子: SELECT CONVERT('test', CHAR CHARACTER SET utf8); SELECT CAST('test' AS CHAR CHARACTER SET utf8); | 语法:CREATE TEMPORARY TABLE new_tbl SELECT * FROM orig_tbl LIMIT 0; 数据库 2019-03-26 16:02:00 摘要:也许你在别的地方听说过Git。也许有人告诉过你,Git只适合软件开发人员。如果你是数据科学家,那么Git其实对你很重要。本文作者希望能够通过经验分享让你了解Git的重要性,以及如何在你的数据科学工作中使用它。 什么是 Git ? Git是一个分布式版本控制系统,用于在软件开发期间跟踪源代码的更改。看看维基百科给出的这个定义,好像Git专门是为软件开发人员而设计的。实际上,Git是当今世界上使用最广泛的现代版本控制系统,它是以分布式的协作方式为项目(开源或商业)做出了伟大的贡献。除了分布式版本控制系统之外,Git的还考虑了性能、安全性和灵活性。现在你已经了解了Git是什么,但是你脑海中的问题可能是,“如果我是做数据科学项目的人,它与我的工作有什么关系?”以前我也一样不能理解Git的重要性,直到我开始在现实工作环境中,我才发现它时如此重要! 为什么是 Git ? 我们来谈谈为什么?一年前,我决定学习Git。我在Github上分享并发布了 我的代码 ,这是我在CERN的论文项目。虽然很难理解Git中常用的术语(git-add、commit、push、pull等),但我知道这在数据科学领域很重要,这使我的数据科学工作比以往任何时候都更加充实。 所以我保持学习状态,并坚持“committing”。当我加入我目前的公司时,我在Git方面的经验就派上了用场,因为Git是跨不同团队进行代码开发和协作的主要方式。更重要的是,当你的组织遵循敏捷软件开发框架时,Git尤其有用,在该框架中,Git的分布式版本控制使整个开发工作流更加高效、快速且易于适应变化。那么什么是版本控制呢?版本控制是一个系统记录一个文件或一组文件随时间的变化,以便你以后可以调用特定的版本。比如说,你是一个数据科学家,与一个团队合作,在这个团队中你和另一个数据科学家在构建机器学习模型的时候,对同一个特征进行工作。如果你对该特征做了一些更改并上传到远程存储库,并且这些更改与主分支合并,那么你的项目现在变成了1.1版本。另一位数据科学家也对版本1.1的相同功能进行了一些更改,新的更改现在与主分支合并。模型就变成1.2版本。在任何时候,如果你的团队发现版本1.2在发布期间有一些错误,他们随时可以调用以前的版本1.1,这就是版本控制的美妙之处。 作为数据科学家如何使用 Git ? 我们已经讨论过什么是Git及其重要性。现在的问题归结为:作为数据科学家如何使用Git?作为数据科学家,你不需要成为一个Git领域的专家。关键是要理解Git技术的工作流程以及如何在日常工作中使用Git。准确地说,我在这里使用的是Git Feature Branch Workflow,它通常被开源和商业项目使用。如果你想更多地了解这里使用的术语, 点击这里进行了解 。 Git Feature Branch Workflow Feature Branch Workflow像一个中央存储库,master分支代表正式的项目历史记录。开发人员每次开始处理一个新特性时,都会创建一个新的分支,而不是直接提交到他们的本地主分支上。新的分支可以(也应该)推送到中央存储库。在这种情况下,可以在不修改master分支的情况下与其他开发人员共享一个该分支。 在开始执行任何操作之前,请键 入 git remote -v 以确保工作区指向要使用的远程存储库。 1、从主分支开始,创建一个新分 支 git checkout master git pull git checkout -b branch-name 如果总是维护和更新主分支,则切换到本地主分支,并将最新的提交和代码提取到本地主分支。假设你希望创建一个本地分支,向代码中添加一个新功能,并稍后上传到远程存储库。一旦你将最新的代码更新到本地master分支,我们就创建并checkout出一个名为branch-name的新分支,所有的更改都将在此本地分支上进行。这意味着你本地的master分支不会受到任何影响。 2、更新、添加、提交并将更改推送到远程存储库 git status git add 上面我们做了很多操作,让我们详细了解它。一旦发生了一些更新,就将新的操作add到本地分支,并且希望将该操作上传到远程分支,以便合并到远程主分支。git status将输出你对文件的所有更改(跟踪或未跟踪)。在使用git commit-m“your message”提交消息更改之前,你将使用git add 在此阶段,你的更改仅显示在本地分支中。为了使你的更改显示在BitBucket上的远程分支中,你需要使用git push -u origin branch-name命令进行提交。此命令将该分支推送到中央存储库,并且-u表示将其添加为远程跟踪分支。在设置了跟踪分支之后,可以在没有任何参数的情况下调用git push,以自动将新的功能分支推送到BitBucket上的中央存储库。 3、 创建 pull 请求 现在你已经成功地添加了一个新功能并推送到远程分支。你为自己的贡献感到骄傲,你希望在将远程分支与远程主分支合并之前得到团队成员的反馈。在该分支合并到主分支之前,让其他团队成员有机会对其进行审查。你可以在BitBucket上创建pull请求。现在,你的团队成员已经查看了你的代码,并决定在代码可以合并到主代码库-master分支之前,需要你进行一些其他更改。 git status git add 现在,你可以按照与之前相同的步骤进行更改、提交并最终将更新推送到中央存储库。一旦使用了git push,你的更新将自动显示在pull请求中。如果其他人已将目标更改为你所接触的同一代码,则会发生合并冲突,这在工作中很常见。你可以在 这里 看到如何解决合并冲突。一旦一切顺利完成,这些功能将会合并到master分支中。 当我第一次开始学习Git时,我感到非常沮丧,因为我仍然没有真正理解工作流。这也是写这篇文章的主要原因之一,它真正分解并在更高层次的理解上向你解释工作流程。因为我相信,对工作流程中发生的事情有一个清晰的了解将使学习过程更加有效。 作者:【方向】 原文链接 本文为云栖社区原创内容,未经允许不得转载。 数据库 2019-03-25 13:03:00 一个划时代的知识女性——《杨绛传》读书笔记心得感想4300字: 读书可以让我无比的快乐,但是这本书读完心中却满是苦闷,这不是杨先生的苦闷是我的杞人忧天,特别是讲到文革时期的钱杨和女儿、钱老相继撒手人寰的时候,我甚至边落泪边看完的! 以下是我阅读过程中的一些记录,很零星也很琐碎,就全当个人的心得略加记录了! 一、恋家的杨先生 杨绛非常恋家,并不贪玩却贪看书,回家还帮助父亲做些事情。有一次,杨荫杭(杨绛的父亲)问她:“阿季(杨绛原名杨季康),三天不让你看书,你怎么样?”“不好过。”杨绛说。一星期不让你看书呢?”“一星期都白过了。”杨荫杭笑道:“我也这样。 也许我们现在娱乐活动太丰富,科技发展太快,如果他们父女间对话中的书改成手机是不是和当下贴切多了。 二、钱老的“痴气” 杨绛介绍说:“锺书的‘痴气’书本里灌注不下,还洋溢出来。我们在牛津时,他午睡,我临帖,可是一个人写写字困上来,便睡着了。他醒来见我睡了,就饱蘸浓墨,想给我画个花脸。 钱老的“痴”其实也是很可爱的! 比如: 那时杨先生刚刚生完孩子,还在医院里,钱老每天都到产院探望,常苦着脸对杨绛说“我做坏事了”。原来他打翻了墨水瓶,把房东家的桌布染了。杨绛说:“不要紧,我会洗。”“墨水呀!”“墨水也能洗。”他就放心回去。第二天他又“做坏事了”,把台灯砸了。杨绛问明是怎样的灯,她说:“不要紧,我会修。”他又放心回去。下一次他又满面愁虑,说是把门轴弄坏了,门轴两头的门球脱落了一个,门不能关了。杨绛说:“不要紧,我会修。”他又放心回去。 看吧,这哪是什么“痴”啊,明明是可爱,而且从杨先生口中讲出来还略带炫耀的意思呢!这样鲜活的两位大家也只能在书中慢慢品味了! 三、文学创作的小感悟 在创作过程中,无论所介绍的内容是有关别人的,还是她自己的,行文都含蓄、简约,其思想、情感,不予以特别强调,宁肯少说一点儿,给人多些可以回味的东西。所以杨绛的散文处处散发着大气的美,成熟的美。 在杨绛的笔下,没有高大的英雄人物,只有很平常、很普通的人物,不管是可亲可爱的,还是可憎可恶的,抑或是可悲可叹的人物,他们在日常生活中很常见,演绎的是这些寻常人物的家长里短,因而更带有生活气息。 在艺术创造中,想象极其重要,但它必须贴切真实,离不开“判断力”的调控。杨绛通过对众多作品的分析,理出形象思维与逻辑思维的关系:“小说家的构思,一方面靠想象力的繁衍变幻,以求丰富多彩,一方面还靠判断力的修改剪裁,以求贴合人生真相。前者是形象思维,后者是逻辑思维,二种思维同时并用。 近日在看这本书的同时也找了些杨绛的散文来看,看完以后受益匪浅,然而自己的创作却进入的死胡同,每每一篇很简单的文章都要几经修改,甚至写到一半写不下去,骆驼祥子好词好句(http://www.simayi.net/dushubiji/735.html)又不得不推翻重来,这个过程很痛苦,我和朋友玩笑这种感觉有点像不孕不育或者根本就是难产。曾经一气呵成的写作状态突然没有了,苦闷至极。 四、传统的知识女性和一生的相爱 杨绛待人接物,一招一式无不透出中国传统文化的底蕴。陈子谦曾告诉读者他“一直难以忘怀”的一件小事,他写道:“1984年5月我去拜访钱锺书先生,那天是杨先生开的门,她是那样温文尔雅,一副娇小文弱的样子。当钱先生让我坐下以后,杨先生从里屋用旧式茶盘端出两杯茶来,递一杯给我,递一杯给钱先生,然后双手托着茶盘一直背朝里屋退下,直到我告别时她才从里屋出来,满脸微笑送我到门口,我连忙请杨先生留步,只有钱先生送我下楼。杨先生端茶的动作,特别是她的‘却行’显然是一种旧式礼节,这在当时我真还觉得不好理解,特别是对一位后生晚学,何必如此‘讲礼’,这般客气?我真是谜一般地猜不透他们的心蕴。现在看来,这就叫文化,这就是我们的传统,不管你如何漂洋过海,懂得多少门外语,受多少西洋风气的影响,到头来骨子里的还是本民族的东西,根子还得牢牢地扎在民族文化的传统中。 是的就是他们对传统的认知,也是相互的爱慕。 又比如: 杨绛夫妇医院病床对谈的情景:夜渐深,敲窗的雨声时缓时紧,大颗小粒的雨珠沿着玻璃拉长,零碎地折射进星星点点的光亮。 “季康,不是说咱们找的人手明天就来吗?明天你就回家吧。”黑暗里钱锺书说。“这怎么行?咱这只是从帮忙辅助的意义上找的人,我不走。”折叠床上的杨绛说。“你可以站在一旁看看她做,看过了你总该放心,就明天一天啊。” “默存,我发现《槐聚诗存》上有几处我抄错了字,书都印出来了,这可怎么好?”“打岔,说你该回家的事。”“我怎么能把你的诗抄错了呢?真是的。我怎么会抄错了呢……”小床上她叹着气。“明天你就回家去吧。……”没有回答。在被街衢道路包围的医院里,夜深时总能听见车声。雨地过车声又有不同。床头柜那边传来钱锺书摸索的动静。杨绛问:“找安眠药?”“睡不着,闹离愁了吧?吃一片吧。不用你,不用开灯。” 杨绛起身,按亮壁灯,端上温开水,看着丈夫服下舒乐安。她自己也拈出一片,钱锺书伸手接住。杨绛争道:“这不公平,在家时不是我吃安眠药你也陪着吃吗?你说过中毒俩一块中,岂可让我独中乎?” 就是这样,连安眠药都要分享,这就他们一辈子的爱,在钱老生病的过程中他们的唯一的孩子去世了,读着读着我的眼眶也湿了,好像还轻轻的呜咽起来!???? 五、反倒成了被安抚者 据舒展介绍,钱锺书离世后,他的老伴去看望杨绛,一进门还没说话,只见杨绛孤身一人,老伴就抑制不住抽泣,后来干脆放声大哭起来。杨绛拉着她的手,让她坐到沙发上说:“你比钱瑗小四岁吧?傻孩子,我都挺过来了,你还这样哀伤?你不懂呀,如果我走在女儿和锺书前面,你想想,钱瑗、锺书受得了吗?所以,这并不是坏事,你往深处想想,让痛苦的担子由我来挑,这难道不是一件好事吗?”舒展的老伴回来向他传述以后,他说:“瞧你这点出息,让你去安慰老太太,反倒成了被安抚者。” 六、读书就是精神家园 解放前钱锺书和我寓居上海。我们必读的刊物是《生活周报》。寓所附近有一家生活书店,我们下午四点后经常去看书看报;在那儿会碰见许多熟人,和店里工作人员也熟。有一次,我把围巾落在店里了。回家不多久就接到书店的电话:“你落了一条围巾。恰好傅雷先生来,他给带走了,让我通知你一声。”傅雷带走我的围巾是招我们到他家去夜谈;嘱店员打电话是免我寻找失物。这件小事唤起了我当年的感受:生活书店是我们这类知识分子的精神家园。 是啊,读书就是可以丰富人精神的,他就是所有人的精神家园只是我们现在的阅读渠道太多了反而被束缚住了吧。 七、她就是我唯一的杰作 杨绛在《我们的钱瑗》中以《尖兵钱瑗》作为代序,说钱瑗:“她既然只求当尖兵,可说有志竟成,没有虚度此生。”杨绛回忆早年与丈夫钱锺书在探讨女儿个性时,钱锺书说她:“刚正,像外公;爱教书,像爷爷。”两位祖父迥然不相同的性格,在钱瑗身上表现得都很突出。杨绛在文章中提及钱瑗坚强不屈,正直不阿。北师大曾和英国合作培养“英语教学”研究生。钱瑗常和英方管事人争执,怪他们派来的专家英语水平不高,不合北师大英语研究生的要求。结果英国大使请她吃晚宴,向她道歉,同时也请她说说她的计划和要求。钱瑗的回答头头是道,英大使听了点头称善。杨绛听女儿讲了,也明白她是在建立一项有用的学科。 所以说杨先生总说钱瑗是他唯一的杰作,但从钱授的治学上来说,这是令人佩服的,当然英年早逝,也确实让人觉得万分惋惜。 八、论语的指导意义到今天还是有用的 杨绛对《论语》有很独特的见解。她说《论语》最有趣,“读《论语》,读的是一句一句话,看见的却是一个一个人,书里的一个个弟子,都是活生生的,一人一个样儿,各不相同”。 很久之前看了《孔子如来》好像也是这样的,孔夫子与弟子们的对话确实是鲜活的,却又可以把道理说得浅显,让人一看就明白,当然真要明白其所以然的话,还要颇费周章的,毕竟太过久远了,当然还有一层原因,就是我的悟性太低了吧。 九、杨先生的教育观念是超前的 我体会,‘好的教育’首先是启发人的学习兴趣,学习的自觉性,培养人的上进心,引导人们好学,和不断完善自己。要让学生在不知不觉中受教育,让他们潜移默化。这方面榜样的作用很重要,言传不如身教。我自己就是受父母师长的影响,由淘气转向好学的。爸爸说话入情入理,出口成章,《申报》评论一篇接一篇,浩气冲天,掷地有声。我佩服又好奇,请教秘诀,爸爸说:‘哪有什么秘诀?多读书,读好书罢了。杨绛称:“我对现代教育知道的不多。从报上读到过美术家韩美林作了一幅画,送给两三岁的小朋友,小孩子高高兴兴地回去了,又很快把画拿来要韩美林签名,问他签名干什么,小孩说:‘您签了名,这画才值钱!’可惜呀,这么小的孩子已受到社会不良风气的影响,价值观的教育难道不应引起注意吗?” 关于教育这个话题,杨先生的教育方式还是非常超前的,关于韩美林的这个小故事来说,也确实是让我们有所反思。我们当前的教育是不是存在着价值观的取向问题,是我们相关做教育的人来说颇值得关注的,也是应该予以纠偏的事实所在。 十、过年的年味丧失和我们的价值观有关 旧派过旧历年,新派过新历年。但此所谓过年,非空言度过之谓,其意盖指祭祖报神……今世年终所祭之神,固非耶教之上帝,亦非儒家之先圣先贤,不过五路财神耳。此所谓神,近于魔鬼,此所谓祭,近于行贿。” 一句贿赂五路财神,诠释了我们当前对于过年的偏颇,也一针见血的指出了当前社会的唯金钱论的诡异的价值观。现在的人们不得不从中汲取些营养,让我们的小一辈能够在正常的价值观中茁壮的成长。 十一、钱杨的婚姻是经过风雨洗刷的 对于时代,我是落伍者,没有什么良言贡献给现代婚姻。只是在物质至上的时代潮流下,想提醒年轻的朋友,男女结合最最重要的是感情,双方互相理解的程度,理解深才能互相欣赏吸引、支持和鼓励,两情相悦。我以为,夫妻间最重要的是朋友关系,即使不能做知心的朋友,也该是能做得伴侣的朋友或互相尊重的伴侣。门当户对及其他,并不重要。” 看看,杨先生对于婚姻的现状是有预知的,我们的婚姻与爱情已经是如此的物质化了,所以那些所谓不相信爱情的实质是自己把爱情弄岔了,还是杨先生的爱情是经得起风雨和细细品位的。杨先生也从未落伍。 十二、最大的功劳是保住了钱老的痴气 我最大的功劳是保住了钱锺书的淘气和那一团痴气。这是钱锺书的最可贵处。他淘气、天真,加上他过人的智慧,成了现在众人心目中博学而又风趣的钱锺书。他的痴气得到众多读者的喜爱。但是这个钱锺书成了他父亲一辈子担心的儿子,而我这种“洋盘媳妇”,在钱家是不合适的。 一个饱读诗书,留学海外,精通多国外语的时代女性却又是如此的传统。这种相夫教子中成长起来的女性,一路成全丈夫又不断成就自己远比一门心思嫁入豪门来的有趣的多。 数据库 2019-03-19 22:21:00 概述 阿里云数据管理DMS在云端可提供专业的数据库服务,除对标本地数据库软件的基础功能外,还包含性能诊断、数据追踪、跨实例SQL查询(含异构数据库类型之间)等专业性功能,同时提供审计安全和企业级数据库管理服务。 如果您的数据库在阿里云上均可享受这些服务,但在此之前,如果您的数据库在本地或其它云上,则无法免费享受这些服务。为满足自建数据库的管理诉求,主流所使用的解决方案如: 购买VPC专用网络,需要耗费大量成本,一般不适用于小企业或个人用户; 使用给数据库暴露公网端口的方式,这显然是极为不安全的做法,尤其是生产环境不能接受此类处理; 由用户自己做服务请求的转发,不但稳定性得不到保障,对于用户而言,门槛也很高。 因此DMS正式推出了: “数据库网关”服务 ,让您可安全、0成本地将本地数据库或其它云端数据库 (包含本地IDC自建、其他云数据库、其他云服务器上自建的数据库) 接入阿里云DMS,帮助用户打通云上云下资源,使用一套工具即可轻松实现数据库统一管理。从此您不必再担心因为给数据库开放公网端口产生的安全问题、维护成本等问题。 全新接入方案 1、架构图: (1)本地机房需安装一个数据库网关 (1个互通的网络内仅需要安装1个网关) 。 (2)数据库网关所在机器通过访问公网的DMS Proxy建立连接,该连接将使用https进行加密。 (3)云端DMS(及后续其它数据库产品)对用户进行鉴权后,访问到DB Proxy,DB Proxy再通过步骤2建立的加密通信连接访问到本地数据库网关,本地数据库网关再访问到您的具体数据库。 2、接入云服务方式对比: 3、实操接入,仅需四步: (1)添加网关 :进入DMS控制台,从左侧:“网关配置”中进去,点击添加网关,如下图所示(一个网关可对应一个内部网络,一个网关上可以添加多个数据库地址): (2)下载网关程序 :该程序由Java编写,可反编译进行Review代码,DMS承诺只提供云端您主动发起过的数据库操作。您可以直接点击下载安装包或拷贝wget命令到对应需要安装网关的机器上进行执行(请确保该机器事先安装JRE 1.7以上版本且能够顺畅地访问公网) (3)启动本地网关 :下载后的网关程序解压,进入目录:dms-db-gateway/bin,该目录有2个文件:start.sh/start.bat(Linux和Mac使用start.sh文件,Windows使用start.bat),如下图所示: 此时本地网关如果启动成功,状态会自动更新,并显示“下一步”按钮。本地安装需输入一些阿里云的账号认证信息及随机验证码,便于确认本地网关由本人启动及后期的安全认证,请根据页面上具体的操作提示完成即可。 (4)向网关中添加数据库 :一个网关可以添加多个数据库,本地启动后就可以开始添加了,填写的地址也是本地内网地址(即通过网关所在宿主机去访问数据库的地址),如下图所示: 接下来您就可以通过DMS控制台的“快捷登录->非阿里云库(自建IDC)”进行数据库登录了,也可以在“资源列表”页面登录这些数据库。同时,在这2个页面上可以继续添加本地数据库也可以。 补充说明 :在这里添加的数据库本地数据库,可以在实例授权功能中,授权给子账号,与云上RDS的操作非常类似,后续还会提供这些资源的安全管控和审计等功能。 释放强大服务能力 数据库网关是DMS刚推出的新特性,支持的数据库种类和功能还需有更多提升,未来我们将从以下几个角度为大家提供更多的服务: 1、数据库类型增加: 目前仅支持MySQL数据库类型,后续将会逐步完善支持的数据库类型与阿里云上对齐。 2、功能增强: 目前还未支持性能诊断、数据追踪、跨实例SQL操作等功能,由于在新的技术架构下,这些功能还需进行兼容性处理。还将会为大家提供线上和线下数据资源的对比、迁移、同步、JOIN等操作。 3、相关数据库产品服务: 除DMS产品外,后期会有更多的数据库产品会通过该数据库网关访问本地数据库及其他云端的数据库,例如:企业级DMS、HDM等等,这将为您提供更强大的数据库支持能力。 总结 数据库网关接入后,您的本地数据库享受到阿里云上所提供的数据库产品服务,使得云上云下、跨云之间实现统一管理和自由的数据流动和合并。 详情可移步了解: https://help.aliyun.com/document_detail/102974.html 点击观看DMS发布会 → https://yq.aliyun.com/live/851 专家解读产品年度升级,更有阿里云数据库实验室重磅亮相 DMS企业版超低门槛体验,了解更多产品特性,欢迎访问 : https://promotion.aliyun.com/ntms/act/dmsenterprise.html 原文链接 数据库 2019-03-06 17:29:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 1、汇总 1.1、问题 多套tidb集群的pd 部署在同样的机器,pd的服务相同,导致pd无法启动 版本:2.1.2 1.2、问题及解决 修改相关文件的端口部分解决 2、具体 2.1、具体问题 2.1.1、系统服务 /etc/systemd/system pd.service 2.1.2、pd的启停脚本 【${deploy_dir}/scripts/start_pd.sh】 #!/bin/bash set -e # WARNING: This file was auto-generated. Do not edit! # All your edit might be overwritten! sudo systemctl start pd.service 【 ${deploy_dir} /scripts/stop_pd.sh】 #!/bin/bash set -e # WARNING: This file was auto-generated. Do not edit! # All your edit might be overwritten! sudo systemctl stop pd.service 郑州冶疗男性不孕不育医院哪家好:http://byby.zztjyy.com/ 2.2、修复 tidb中控机: 【1、更改部署的】 /work/tidb/tidb-ansible-2.1/roles/pd/tasks/ systemd_deployment.yml 更改: service_name: pd- {{ pd_client_port }} 【2、滚动升级的】 /work/tidb/tidb-ansible-2.1/ rolling_update.yml 更改: - name: stop PD by systemd systemd: name=pd -{{ pd_client_port }} .service state=stopped http://www.chacha8.cn/detail/1132398232.html - name: start PD by systemd systemd: name=pd -{{ pd_client_port }} .service state=started 【3、更改start的】 /work/tidb/tidb-ansible-2.1/ start.yml - name: start PD by systemd systemd: name=pd- {{ pd_client_port }} .service state=started 2.3、修复后结果 手动删除目标pd机器的: ${deploy_dir}/scripts/start_pd.sh ${ deploy_dir } /scripts/stop_pd.sh ${ deploy_dir } /scripts/run_pd.sh 中控机重新部署: ansible-playbook deploy.yml -l pd机器IP 检查: start_pd.sh #!/bin/bash set -e # WARNING: This file was auto-generated. Do not edit! # All your edit might be overwritten! sudo systemctl start pd-10000 .service stop_pd.sh #!/bin/bash set -e # WARNING: This file was auto-generated. Do not edit! # All your edit might be overwritten! sudo systemctl stop pd-10000 .service cd /etc/systemd/system pd-10000 .service 数据库 2019-09-26 16:55:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 作者 | 声东 阿里云售后技术专家 以我的经验来讲,理解 Kubernetes 集群服务的概念,是比较不容易的一件事情。尤其是当我们基于似是而非的理解,去排查服务相关问题的时候,会非常不顺利。 这体现在,对于新手来说,ping 不通服务的 IP 地址这样基础的问题,都很难理解;而就算对经验很丰富的工程师来说,看懂服务相关的 iptables 配置,也是有相当的挑战的。 今天这边文章,我来深入解释一下 Kubernetes 集群服务的原理与实现,便于大家理解。 Kubernetes 集群服务的本质是什么 概念上来讲,Kubernetes 集群的服务,其实就是负载均衡、或反向代理。这跟阿里云的负载均衡产品,有很多类似的地方。和负载均衡一样,服务有它的 IP 地址以及前端端口;服务后边会挂载多个容器组 Pod 作为其“后端服务器”,这些“后端服务器”有自己的 IP 以及监听端口。 当这样的负载均衡和后端的架构,与 Kubernetes 集群结合的时候,我们可以想到的最直观的实现方式,就是集群中某一个节点专门做负载均衡(类似 LVS)的角色,而其他节点则用来负载后端容器组。 这样的实现方法,有一个巨大的缺陷,就是单点问题。Kubernetes 集群是 Google 多年来自动化运维实践的结晶,这样的实现显然与其智能运维的哲学相背离的。 自带通信员 边车模式(Sidecar)是微服务领域的核心概念。边车模式,换一句通俗一点的说法,就是自带通信员。熟悉服务网格的同学肯定对这个很熟悉了。但是可能比较少人注意到,其实 Kubernetes 集群原始服务的实现,也是基于 Sidecar 模式的。 在 Kubernetes 集群中,服务的实现,实际上是为每一个集群节点上,部署了一个反向代理 Sidecar。而所有对集群服务的访问,都会被节点上的反向代理转换成对服务后端容器组的访问。基本上来说,节点和这些 Sidecar 的关系如下图所示。 把服务照进现实 前边两节,我们看到了,Kubernetes 集群的服务,本质上是负载均衡,即反向代理;同时我们知道了,在实际实现中,这个反向代理,并不是部署在集群某一个节点上,而是作为集群节点的边车,部署在每个节点上的。 在这里把服务照进反向代理这个现实的,是 Kubernetes 集群的一个控制器,即 kube-proxy。关于 Kubernetes 集群控制器的原理,请参考我另外一篇 关于控制器的文章 。简单来说,kube-proxy 作为部署在集群节点上的控制器,它们通过集群 API Server 监听着集群状态变化。当有新的服务被创建的时候,kube-proxy 则会把集群服务的状态、属性,翻译成反向代理的配置。 那剩下的问题,就是反向代理,即上图中 Proxy 的实现。 一种实现 Kubernetes 集群节点实现服务反向代理的方法,目前主要有三种,即 userspace、iptables 以及 IPVS。今天我们只深入分析 iptables 的方式,底层网络基于阿里云 Flannel 集群网络。 过滤器框架 现在,我们来设想一种场景。我们有一个屋子。这个屋子有一个入水管和出水管。从入水管进入的水,是不能直接饮用的,因为有杂质。而我们期望,从出水管流出的水,可以直接饮用。为了达到目的,我们切开水管,在中间加一个杂质过滤器。 过了几天,我们的需求变了,我们不止要求从屋子里流出来的水可以直接饮用,我们还希望水是热水。所以我们不得不再在水管上增加一个切口,然后增加一个加热器。 很明显,这种切开水管,增加新功能的方式是很丑陋的。因为需求可能随时会变,我们甚至很难保证,在经过一年半载之后,这跟水管还能找得到可以被切开的地方。 所以我们需要重新设计。首先我们不能随便切开水管,所以我们要把水管的切口固定下来。以上边的场景为例,我们确保水管只能有一个切口位置。其次,我们抽象出对水的两种处理方式:物理变化和化学变化。 基于以上的设计,如果我们需要过滤杂质,就可以在化学变化这个功能模块里增加一条过滤杂质的规则;如果我们需要增加温度的话,就可以在物理变化这个功能模块里增加一条加热的规则。 以上的过滤器框架,显然比切水管的方式,要优秀很多。设计这个框架,我们主要做了两件事情,一个是固定水管切口位置,另外一个是抽象出两种水处理方式。 理解这两件事情之后,我们可以来看下 iptables,或者更准确的说法,netfilter 的工作原理。netfilter 实际上就是一个过滤器框架。netfilter 在网络包收发及路由的管道上,一共切了 5 个口,分别是 PREROUTING,FORWARD,POSTROUTING,INPUT 以及 OUTPUT;同时 netfilter 定义了包括 nat、filter 在内的若干个网络包处理方式。 需要注意的是,routing 和 forwarding 很大程度上增加了以上 netfilter 的复杂程度,如果我们不考虑 routing 和 forwarding,那么 netfilter 会变得跟我们的水质过滤器框架一样简单。 节点网络大图 现在我们看一下 Kubernetes 集群节点的网络全貌。横向来看,节点上的网络环境,被分割成不同的网络命名空间,包括主机网络命名空间和 Pod 网络命名空间;纵向来看,每个网络命名空间包括完整的网络栈,从应用到协议栈,再到网络设备。 在网络设备这一层,我们通过 cni0 虚拟网桥,组建出系统内部的一个虚拟局域网。Pod 网络通过 veth 对连接到这个虚拟局域网内。cni0 虚拟局域网通过主机路由以及网口 eth0 与外部通信。 在网络协议栈这一层,我们可以通过编程 netfilter 过滤器框架,来实现集群节点的反向代理。 实现反向代理,归根结底,就是做 DNAT,即把发送给集群服务 IP 和端口的数据包,修改成发给具体容器组的 IP 和端口。 参考 netfilter 过滤器框架的图,我们知道,在 netfilter 里,可以通过在 PREROUTING,OUTPUT 以及 POSTROUGING 三个位置加入 NAT 规则,来改变数据包的源地址或目的地址。 因为这里需要做的是 DNAT,即改变目的地址,这样的修改,必须在路由(ROUTING)之前发生以保证数据包可以被路由正确处理,所以实现反向代理的规则,需要被加到 PREROUTING 和 OUTPUT 两个位置。 其中,PREOURTING 的规则,用来处理从 Pod 访问服务的流量。数据包从 Pod 网络 veth 发送到 cni0 之后,进入主机协议栈,首先会经过 netfilter PREROUTING 来做处理,所以发给服务的数据包,会在这个位置做 DNAT。经过 DNAT 处理之后,数据包的目的地址变成另外一个 Pod 的地址,从而经过主机路由,转发到 eth0,发送给正确的集群节点。 而添加在 OUTPUT 这个位置的 DNAT 规则,则用来处理从主机网络发给服务的数据包,原理也是类似,即经过路由之前,修改目的地址,以方便路由转发。 升级过滤器框架 在过滤器框架一节,我们看到 netfilter 是一个过滤器框架。netfilter 在数据“管到”上切了 5 个口,分别在这 5 个口上,做一些数据包处理工作。虽然固定切口位置以及网络包处理方式分类已经极大的优化了过滤器框架,但是有一个关键的问题,就是我们还是得在管道上做修改以满足新的功能。换句话说,这个框架没有做到管道和过滤功能两者的彻底解耦。 为了实现管道和过滤功能两者的解耦,netfilter 用了表这个概念。表就是 netfilter 的过滤中心,其核心功能是过滤方式的分类(表),以及每种过滤方式中,过滤规则的组织(链)。 把过滤功能和管道解耦之后,所有对数据包的处理,都变成了对表的配置。而管道上的5个切口,仅仅变成了流量的出入口,负责把流量发送到过滤中心,并把处理之后的流量沿着管道继续传送下去。 如上图,在表中,netfilter 把规则组织成为链。表中有针对每个管道切口的默认链,也有我们自己加入的自定义链。默认链是数据的入口,默认链可以通过跳转到自定义链来完成一些复杂的功能。这里允许增加自定义链的好处是显然的。为了完成一个复杂过滤功能,比如实现 Kubernetes 集群节点的反向代理,我们可以使用自定义链来模块化我们规则。 用自定义链实现服务的反向代理 集群服务的反向代理,实际上就是利用自定义链,模块化地实现了数据包的 DNAT 转换。KUBE-SERVICE 是整个反向代理的入口链,其对应所有服务的总入口;KUBE-SVC-XXXX 链是具体某一个服务的入口链,KUBE-SERVICE 链会根据服务 IP,跳转到具体服务的 KUBE-SVC-XXXX 链;而 KUBE-SEP-XXXX 链代表着某一个具体 Pod 的地址和端口,即 endpoint,具体服务链 KUBE-SVC-XXXX 会以一定算法(一般是随机),跳转到 endpoint 链。 而如前文中提到的,因为这里需要做的是 DNAT,即改变目的地址,这样的修改,必须在路由之前发生以保证数据包可以被路由正确处理。所以 KUBE-SERVICE 会被 PREROUTING 和 OUTPUT 两个默认链所调用。 总结 通过这篇文章,大家应该对 Kubernetes 集群服务的概念以及实现,有了更深层次的认识。我们基本上需要把握三个要点: 服务本质上是负载均衡; 服务负载均衡的实现采用了与服务网格类似的 Sidecar 的模式,而不是 LVS 类型的独占模式; kube-proxy 本质上是一个集群控制器。除此之外,我们思考了过滤器框架的设计,并在此基础上,理解使用 iptables 实现的服务负载均衡的原理。 原文链接 本文为云栖社区原创内容,未经允许不得转载。 数据库 2019-09-24 13:53:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 1. 什么是事务?事务的特性(ACID)? 答:事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么都成功,要么都失败)。 事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所有操作。 事务的特性有:原子性(Atomicity),隔离性(Isolation),一致性( Consistency),持续性(Durability) 原子性:事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做 一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。 隔离性 :一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。 持续性 :也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。 2.事务的隔离级别有几种?最常用的隔离级别是哪两种(提交读、可重复读)? 答:并发过程中会出现的问题: 丢失更新:提交一个事务时,把其他事务已提交的更新数据覆盖。 脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。 幻读也叫虚读:一个事务执行两次查询,第二次结果集包含第一次中没有或某些行已经被删除的数据,造成两次结果不一致,只是另一个事务在这两次查询中间插入或删除了数据造成的。幻读是事务非独立执行时发生的一种现象。 不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异,不可被信任。 事务的四种隔离级别: 未提交读:就是一个事务读取到其他事务未提交的数据,是级别最低的隔离机制。缺点: 会产生脏读、不可重复读、幻读。 提交读:就是一个事务读取到其他事务提交后的数据。Oracle默认隔离级别。缺点:会产生不可重复读、幻读。 可重复读:就是一个事务对同一份数据读取到的相同,不在乎其他事务对数据的修改。MySQL默认的隔离级别。缺点:会产生幻读。 可串行化:事务串行化执行,隔离级别最高,牺牲了系统的并发性。缺点:可以解决并发事务的所有问题。但是效率地下,消耗数据库性能,一般不使用。 3. 什么是索引? 答: 索引其实是一种数据结构,能够帮助我们快速的检索数据库中的数据。 4. 索引具体采用的哪种数据结构呢? 答: 常见的MySQL主要有两种结构:Hash索引和B+ Tree索引,通常使用的是InnoDB引擎,默认的是B+树。当选用memory引擎的时候,就是用的Hash索引。 5. B+ Tree索引和Hash索引区别? 哈希索引适合等值查询,但是无法进行范围查询。 哈希索引没办法利用索引完成排序。 哈希索引不支持多列联合索引的最左匹配规则。 如果有大量重复键值的情况下,哈希索引的效率会很低,因为存在哈希碰撞问题。 6. B+ Tree的叶子节点都可以存哪些东西吗? 他们之间有什么区别? 答:InnoDB的B+ Tree可能存储的是整行数据,也有可能是主键的值。区别:在 InnoDB 里,索引B+ Tree的叶子节点存储了整行数据的是主键索引,也被称之为聚簇索引。而索引B+ Tree的叶子节点存储了主键的值的是非主键索引,也被称之为非聚簇索引。 7. 聚簇索引和非聚簇索引,在查询数据的时候有区别吗? 答:聚簇索引查询会更快,因为主键索引树的叶子节点直接就是我们要查询的整行数据了。而非主键索引的叶子节点是主键的值,查到主键的值以后,还需要再通过主键的值再进行一次查询。 8. 主键索引查询只会查一次,而非主键索引需要回表查询多次(这个过程叫做回表)。是所有情况都是这样的吗?非主键索引一定会查询多次吗? 答:覆盖索引(covering index)指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取。也可以称之为实现了索引覆盖。当一条查询语句符合覆盖索引条件时,MySQL只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后再返回表操作,减少I/O提高效率。 如,表covering_index_sample中有一个普通索引 idx_key1_key2(key1,key2)。当我们通过SQL语句:select key2 from covering_index_sample where key1 = 'keytest';的时候,就可以通过覆盖索引查询,无需回表。 9. 在创建索引的时候都会考虑哪些因素呢?在创建联合索引的时候,需要做联合索引多个字段之间顺序,这是如何选择的呢? 答:一般对于查询概率比较高,经常作为where条件的字段设置索引。在创建多列索引时,我们根据业务需求,where子句中使用最频繁的一列放在最左边,因为MySQL索引查询会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。 所以当我们创建一个联合索引的时候,如(key1,key2,key3),相当于创建了(key1)、(key1,key2)和(key1,key2,key3)三个索引,这就是最左匹配原则。 10. 那什么情况下会发生明明创建了索引,但是执行的时候并没有通过索引呢? 在一条单表查询语句真正执行之前,MySQL的查询优化器会找出执行该语句所有可能使用的方案,对比之后找出成本最低的方案。这个成本最低的方案就是所谓的执行计划。优化过程大致过程:根据搜索条件,找出所有可能使用的索引;计算全表扫描的代价;计算使用不同索引执行查询的代价;对比各种执行方案的代价,找出成本最低的那一个。 11. 为什么索引结构默认使用B+Tree,而不是Hash,二叉树,红黑树? B+tree是一种多路平衡查询树,节点是天然有序的,非叶子节点包含多个元素,不保存数据,只用来索引,叶子节点包含完整数据和带有指向下一个节点的指针,形成一个有序链表,有助于范围和顺序查找。因为非叶子节点不保存数据,所以同样大小的磁盘页可以容纳更多的元素,同样能数据量的情况下,B+tree相比B-tree高度更低,因此查询时IO会更少。 B-tree不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少(有些资料也称为扇出),指针少的情况下要保存大量数据,只能增加树的高度,导致IO操作变多,查询性能变低; Hash索引底层是基于哈希表,就是以key-value存储数据的结构,多个数据在存储关系上是没有任何顺序关系的。只适合等值查询,不适合范围查询,而且也无法利用索引完成排序,不支持联合索引的最左匹配原则,如果有大量重复键值的情况下,哈希索引效率会很低,因为存在哈希碰撞。 二叉树:树的高度不均匀,不能自平衡,查找效率跟数据有关(树的高度),并且IO代价高。 红黑树:树的高度随着数据量增加而增加,IO代价高。 12. 如何优化MySQL? 答:MySQL优化大致可以分为三部分:索引的优化、SQL语句优化和表的优化 索引优化可以遵循以下几个原则: 联合索引最左前缀匹配原则( 但是这里有一种特殊的情况,如果将一个表中除ID意外的所有字段都组成一个联合索引,那么这个时候就不会遵循最左原则,这个时候无论怎么以哪个字段为where条件,都将用到这个索引。但是当有一个字段没有在这个联合索引索引里面的时候,就会遵循最左原则 ) 尽量把字段长度小的列放在联合索引的最左侧(因为字段越小,一页存储的数据量越大,IO性能也就越好) order by 有多个列排序的,应该建立联合索引 对于频繁的查询优先考虑使用覆盖索引 前导模糊查询不会使用索引,比如说Like '%aaa%'这种,但是可以在mysql中创建全文索引 负向条件不会使用索引,如!=,<>,not like,not in,not exists 索引应该建立在区分度比较高的字段上,一般区分度在80%以上的时候就可以建立索引,区分度可以使用 count(distinct(列名))/count(*) 对于where子句中经常使用的列,最好设置索引 or两边的字段需要索引 SQL语句优化,可以通过explain查看SQL的执行计划,优化语句原则可以有: 在where和order by涉及的列上建立合适的索引,避免全表扫描 任何查询都不要使用select * ,而是用具体的字段列表代替(增加了消耗,e.g CPU,IO等,增加了使用覆盖索引的可能性) 多表连接时,尽量小表驱动大表,即小表join大表 用exists代替in(IN是走rang,就是最差的索引=没有索引,而EXISTS走的ref,已经算是比较好的检索方式了) 尽量避免在where字句中对字段进行函数操作(主要是不会触发索引) SQL语句中in包含的值不应过多(In中的常量全部存储在一个数组中,而且这个数组是排好序的,如果数值较多,产生的消耗也是比较大的) 当只需要一条数据的时候,使用limit 1 如果排序字段没有用到索引,就尽量少排序 尽量用union all代替union(union需要将结果集合并后再进行唯一性过滤操作,会增加大量的CPU运算,加大资源消耗和延迟。当然,前提是union all的前提是两个结果集没有重复的数据) 不要使用Order by rand() in和exists主要是驱动顺序的改变,exists是以外层表为驱动,先被访问;in是先执行子查询。所以in适合于外表大而内表小,exists适合于外表小而内表大的情况, not in和not exists同理 对于分页查询,可以考虑获取前一页的最大的id,用where id > num left join是以左边表为驱动;right join是以右边表为驱动,inner join会自动找出那个数据少的表作为驱动表 数据库表优化 表字段尽可能用not null 字段长度固定表查询会更快 将数据库大表按照时间或者一些标志拆分成小表 水平拆分:将记录散列到不同的表中,每次从分表查询 垂直拆分:将表中的大字段单独拆分到另一张表,形成一对一的关系 数据库 2019-09-20 12:41:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 作者 | 元乙 阿里云日志服务数据采集客户端负责人,目前采集客户端 logtail 在集团百万规模部署,每天采集上万应用数 PB 数据,经历多次双 11、双 12 考验。 导读: 随着 K8s 不断更新迭代,使用 K8s 日志系统建设的开发者,逐渐遇到了各种复杂的问题和挑战。本篇文章中,作者结合自己多年经验,分析 K8s 日志系统建设难点,期待为读者提供有益参考。 在 Logging 这块做了几年,最近 1 年来越来越多的同学来咨询如何为 Kubernetes 构建一个日志系统,或者是来求助在这过程中遇到一系列问题如何解决,授人以鱼不如授人以渔,于是想把我们这些年积累的经验以文章的形式发出来,让看到这篇文章的同学能少走弯路。这个系列文章定位为长篇连载,内容偏向落地实操以及经验分享,且内容会随着技术的迭代而不定期更新。 前言 第一次听到 Kubernetes 的名字是在 2016 年,那个时候 Kubernetes 还处于和 Docker Swarm、Mesos 方案的“三国鼎立时代”,Kubernetes 由于一系列优势(可扩展、声明式接口、云友好)在这一竞争中崭露头角,最终获得统治地位。 Kubernetes 作为 CNCF 最核心的项目(没有之一),是 Cloud Native(云原生)落地的底座,目前阿里已经全面基于 Kubernetes 在开展全站的云原生改造,在 1-2 年内,阿里巴巴 100% 的业务都将跑在公有云上。 CloudNative 在 CNCF 的定义 的核心是:在公有云、私有云、混合云等环境中,通过 Containers、Service Meshes、 MicroServices、Immutable Infrastructure、Declarative APIs 构建和运行可弹性扩展的且具有高容错性、易于管理、可观察、松耦合的应用系统。可观察性是应用系统必不可少的一个部分,云原生的设计理念中就有一条:面向诊断性设计(Diagnosability),包括集群级别的日志、Metric 和 Trace。 为何我们需要日志系统 通常一个线上问题的定位流程是:通过 Metric 发现问题,根据 Trace 定位到问题模块,根据模块具体的日志定位问题原因。在日志中包括了错误、关键变量、代码运行路径等信息,这些是问题排查的核心,因此日志永远是线上问题排查的必经路径。 在阿里的十多年中,日志系统伴随着计算形态的发展在不断演进,大致分为 3 个主要阶段: 在单机时代,几乎所有的应用都是单机部署,当服务压力增大时,只能切换更高规格的 IBM 小型机。日志作为应用系统的一部分,主要用作程序 Debug,通常结合 grep 等 Linux 常见的文本命令进行分析; 随着单机系统成为制约阿里业务发展的瓶颈,为了真正的 Scale out,飞天项目启动:2013 年飞天 5K 项目正式上线。在这个阶段各个业务开始了分布式改造,服务之间的调用也从本地变为分布式,为了更好的管理、调试、分析分布式应用,我们开发了 Trace(分布式链路追踪)系统、各式各样的监控系统,这些系统的统一特点是将所有的日志(包括 Metric 等)进行集中化的存储; 为了支持更快的开发、迭代效率,近年来我们开始了容器化改造,并开始了拥抱 Kubernetes 生态、业务全量上云、Serverless 等工作。在这阶段,日志无论从规模、种类都呈现爆炸式的增长,对日志进行数字化、智能化分析的需求也越来越高,因此统一的日志平台应运而生。 可观察性的终极解读 在 CNCF 中,可观察性的主要作用是问题的诊断,上升到公司整体层面,可观察性(Observability)不仅仅包括 DevOps 领域,还包括业务、运营、BI、审计、安全等领域,可观察性的最终的目标是实现公司各个方面的数字化、智能化。 在阿里,几乎所有的业务角色都会涉及到各式各样的日志数据,为了支撑各类应用场景,我们开发了非常多的工具和功能:日志实时分析、链路追踪、监控、数据加工、流计算、离线计算、BI 系统、审计系统等等。日志系统主要专注于数据的实时采集、清洗、智能分析与监控以及对接各类各样的流计算、离线系统。 Kubernetes 日志系统建设难点 单纯日志系统的解决方案非常多,相对也比较成熟,这里就不再去赘述,我们此次只针对 Kubernetes 上的日志系统建设而论。Kubernetes 上的日志方案相比我们之前基于物理机、虚拟机场景的日志方案有很大不同,例如: 日志的形式变得更加复杂,不仅有物理机/虚拟机上的日志,还有容器的标准输出、容器内的文件、容器事件、Kubernetes 事件等等信息需要采集; 环境的动态性变强,在 Kubernetes 中,机器的宕机、下线、上线、Pod销毁、扩容/缩容等都是常态,这种情况下日志的存在是瞬时的(例如如果 Pod 销毁后该 Pod 日志就不可见了),所以日志数据必须实时采集到服务端。同时还需要保证日志的采集能够适应这种动态性极强的场景; 日志的种类变多,上图是一个典型的 Kubernetes 架构,一个请求从客户端需要经过 CDN、Ingress、Service Mesh、Pod 等多个组件,涉及多种基础设施,其中的日志种类增加了很多,例如 K8s 各种系统组件日志、审计日志、ServiceMesh 日志、Ingress 等; 业务架构变化,现在越来越多的公司开始在 Kubernetes 上落地微服务架构,在微服务体系中,服务的开发更加复杂,服务之间的依赖以及服务底层产品的依赖越来越多,这时的问题排查将更加复杂,如果关联各个维度的日志将是一个困难的问题; 日志方案集成困难,通常我们都会在 Kubernetes 上搭建一套 CICD 系统,这套 CICD 系统需要尽可能的自动化的完成业务的集成和部署,其中日志的采集、存储、清洗等也需要集成到这套系统中,并和 K8s 的声明式部署方式尽可能一致。而现有的日志系统通常都是较独立的系统,集成到 CICD 中代价极大; 日志规模问题,通常在系统初期的时候我们会选择自建开源的日志系统,这种方式在测试验证阶段或公司发展初期是没有什么问题的,但当业务逐渐增长,日志量增长到一定规模时,自建的开源系统很多时候都会遇到各种各样的问题,例如租户隔离、查询延迟、数据可靠性、系统可用性等。日志系统虽不是 IT 中最核心的路径,但一旦关键时刻出现这些问题都将是非常可怕的影响,例如大促的时候出现紧急问题,排查时多个工程师并发查询把日志系统打爆,导致故障恢复时间变长,大促收到影响。 相信在搞 K8s 日志系统建设的同学看到上面的难点分析都会深有感触,后面我们会从落地角度出发,详细介绍在阿里我们如何去搭建 K8s 的日志系统,敬请关注。 原文链接 本文为云栖社区原创内容,未经允许不得转载。 数据库 2019-09-19 14:03:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> sql_mode 是一个很容易被忽视的配置,宽松模式下可能会被输入一些非准确数据,所以生产环境下会要求为严格模式,为了保持生产环境和开发环境,测试环境一致性,我们开发环境和测试环境也要配置成为严格模式。 sql_mode常用值 ONLY_FULL_GROUP_BY:在分组查询语句中如果一个select中的列没有在group by中出现,则该语句是不合法的。 NO_AUTO_VALUE_ON_ZERO:在默认情况下自增长列在插入0或NULL时会自动插入下一个自增长值。当设置该模式情况下,插入0时不会进行自增长依然插入0值。 STRICT_TRANS_TABLES:对事务表进行限制,当一个数据不能插入到事务表中时中断当前操作。对非实物表不做限制。 NO_ZERO_IN_DATE:只要日期的月和日中含有0值都报错,但是‘0000-00-00’除外。 NO_ZERO_DATE:只有‘0000-00-00’报错。 ERROR_FOR_DIVISION_BY_ZERO:在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如果非该模式下被0除时mysql返回NULL。 NO_AUTO_CREATE_USER:禁止创建密码为空的用户。 NO_ENGINE_SUBSTITUTION:如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常。 PIPES_AS_CONCAT:将"||"视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似。 ANSI_QUOTES:启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符。 Oracle数据库切换为mysql数据库 只需要修改sql_mode为:PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER。 修改sql_mode模式 通过 "SELECT @@sql_mode;"查看当前数据库模式,修改“SET sql_mode = ‘修改为模式’; ”。这种方式只在当前session生效。 同理:select @@global.sql_mode 和 set global sql_mode = '修改后的值';只在当前服务中生效,重启后失效。 修改my.cnf文件重启,永久生效。 数据库 2019-09-17 20:41:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 最近我们扩展了 TiDB 表达式计算框架,增加了向量化计算接口,初期的性能测试显示,多数表达式计算性能可大幅提升,部分甚至可提升 1~2 个数量级。为了让所有的表达式都能受益,我们需要为所有内建函数实现向量化计算。 TiDB 的向量化计算是在经典 Volcano 模型上的进行改进,尽可能利用 CPU Cache,SIMD Instructions,Pipeline,Branch Predicatation 等硬件特性提升计算性能,同时降低执行框架的迭代开销,这里提供一些参考文献,供感兴趣的同学阅读和研究: MonetDB/X100: Hyper-Pipelining Query Execution Balancing Vectorized Query Execution with Bandwidth-Optimized Storage The Design and Implementation of Modern Column-Oriented Database Systems 在这篇文章中,我们将描述: 如何在计算框架下实现某个函数的向量化计算; 如何在测试框架下做正确性和性能测试; 如何参与进来成为 TiDB Contributor。 表达式向量化 1. 如何访问和修改一个向量 在 TiDB 中,数据按列在内存中连续存在 Column 内,Column 详细介绍请看: TiDB 源码阅读系列文章(十)Chunk 和执行框架简介 。本文所指的向量,其数据正是存储在 Column 中。 我们把数据类型分为两种: 定长类型: Int64 、 Uint64 、 Float32 、 Float64 、 Decimal 、 Time 、 Duration ; 变长类型: String 、 Bytes 、 JSON 、 Set 、 Enum 。 定长类型和变长类型数据在 Column 中有不同的组织方式,这使得他们有如下的特点: 定长类型的 Column 可以随机读写任意元素; 变长类型的 Column 可以随机读,但更改中间某元素后,可能需要移动该元素后续所有元素,导致随机写性能很差。 对于定长类型(如 int64 ),我们在计算时会将其转成 Golang Slice(如 []int64 ),然后直接读写这个 Slice。相比于调用 Column 的接口,需要的 CPU 指令更少,性能更好。同时,转换后的 Slice 仍然引用着 Column 中的内存,修改后不用将数据从 Slice 拷贝到 Column 中,开销降到了最低。 对于变长类型,元素长度不固定,且为了保证元素在内存中连续存放,所以不能直接用 Slice 的方式随机读写。我们规定变长类型数据以追加写( append )的方式更新,用 Column 的 Get() 接口进行读取。 总的来说,变长和定长类型的读写方式如下: 定长类型(以 int64 为例) a. ResizeInt64s(size, isNull) :预分配 size 个元素的空间,并把所有位置的 null 标记都设置为 isNull ; b. Int64s() :返回一个 []int64 的 Slice,用于直接读写数据; c. SetNull(rowID, isNull) :标记第 rowID 行为 isNull 。 变长类型(以 string 为例) a. ReserveString(size) :预估 size 个元素的空间,并预先分配内存; b. AppendString(string) : 追加一个 string 到向量末尾; c. AppendNull() :追加一个 null 到向量末尾; d. GetString(rowID) :读取下标为 rowID 的 string 数据。 当然还有些其他的方法如 IsNull(rowID) , MergeNulls(cols) 等,就交给大家自己去探索了,后面会有这些方法的使用例子。 2. 表达式向量化计算框架 向量化的计算接口大概如下( 完整的定义在这里 ): vectorized() bool vecEvalXType(input *Chunk, result *Column) error XType 可能表示 Int , String 等,不同的函数需要实现不同的接口; input 表示输入数据,类型为 *Chunk ; result 用来存放结果数据。 外部执行算子(如 Projection,Selection 等算子),在调用表达式接口进行计算前,会通过 vectorized() 来判断此表达式是否支持向量化计算,如果支持,则调用向量化接口,否则就走行式接口。 对于任意表达式,只有当其中所有函数都支持向量化后,才认为这个表达式是支持向量化的。 比如 (2+6)*3 ,只有当 MultiplyInt 和 PlusInt 函数都向量化后,它才能被向量化执行。 为函数实现向量化接口 要实现函数向量化,还需要为其实现 vecEvalXType() 和 vectorized() 接口。 在 vectorized() 接口中返回 true ,表示该函数已经实现向量化计算; 在 vecEvalXType() 实现此函数的计算逻辑。 尚未向量化的函数在 issue/12058 中,欢迎感兴趣的同学加入我们一起完成这项宏大的工程。 向量化代码需放到以 _vec.go 结尾的文件中,如果还没有这样的文件,欢迎新建一个,注意在文件头部加上 licence 说明。 这里是一个简单的例子 PR/12012 ,以 builtinLog10Sig 为例: 这个函数在 expression/builtin_math.go 文件中,则向量化实现需放到文件 expression/builtin_math_vec.go 中; builtinLog10Sig 原始的非向量化计算接口为 evalReal() ,那么我们需要为其实现对应的向量化接口为 vecEvalReal() ; 实现完成后请根据后续的说明添加测试。 下面为大家介绍在实现向量化计算过程中需要注意的问题。 1. 如何获取和释放中间结果向量 存储表达式计算中间结果的向量可通过表达式内部对象 bufAllocator 的 get() 和 put() 来获取和释放,参考 PR/12014 ,以 builtinRepeatSig 的向量化实现为例: buf2, err := b.bufAllocator.get(types.ETInt, n) if err != nil { return err } defer b.bufAllocator.put(buf2) // 注意释放之前申请的内存 2. 如何更新定长类型的结果 如前文所说,我们需要使用 ResizeXType() 和 XTypes() 来初始化和获取用于存储定长类型数据的 Golang Slice,直接读写这个 Slice 来完成数据操作,另外也可以使用 SetNull() 来设置某个元素为 NULL 。代码参考 PR/12012 ,以 builtinLog10Sig 的向量化实现为例: f64s := result.Float64s() for i := 0; i < n; i++ { if isNull { result.SetNull(i, true) } else { f64s[i] = math.Log10(f64s[i]) } } 3. 如何更新变长类型的结果 如前文所说,我们需要使用 ReserveXType() 来为变长类型预分配一段内存(降低 Golang runtime.growslice() 的开销),使用 AppendXType() 来追加一个变长类型的元素,使用 GetXType() 来读取一个变长类型的元素。代码参考 PR/12014 ,以 builtinRepeatSig 的向量化实现为例: result.ReserveString(n) ... for i := 0; i < n; i++ { str := buf.GetString(i) if isNull { result.AppendNull() } else { result.AppendString(strings.Repeat(str, int(num))) } } 4. 如何处理 Error 所有受 SQL Mode 控制的 Error,都利用对应的错误处理函数在函数内就地处理。部分 Error 可能会被转换成 Warn 而不需要立即抛出。 这个比较杂,需要查看对应的非向量化接口了解具体行为。代码参考 PR/12042 ,以 builtinCastIntAsDurationSig 的向量化实现为例: for i := 0; i < n; i++ { ... dur, err := types.NumberToDuration(i64s[i], int8(b.tp.Decimal)) if err != nil { if types.ErrOverflow.Equal(err) { err = b.ctx.GetSessionVars().StmtCtx.HandleOverflow(err, err) // 就地利用对应处理函数处理错误 } if err != nil { // 如果处理不掉就抛出 return err } result.SetNull(i, true) continue } ... } 5. 如何添加测试 我们做了一个简易的测试框架,可避免大家测试时做一些重复工作。 该测试框架的代码在 expression/bench_test.go 文件中,被实现在 testVectorizedBuiltinFunc 和 benchmarkVectorizedBuiltinFunc 两个函数中。 我们为每一个 builtin_XX_vec.go 文件增加了 builtin_XX_vec_test.go 测试文件。当我们为一个函数实现向量化后,需要在对应测试文件内的 vecBuiltinXXCases 变量中,增加一个或多个测试 case。下面我们为 log10 添加一个测试 case: var vecBuiltinMathCases = map[string][]vecExprBenchCase { ast.Log10: { {types.ETReal, []types.EvalType{types.ETReal}, nil}, }, } 具体来说,上面结构体中的三个字段分别表示: 该函数的返回值类型; 该函数所有参数的类型; 是否使用自定义的数据生成方法(dataGener), nil 表示使用默认的随机生成方法。 对于某些复杂的函数,你可自己实现 dataGener 来生成数据。目前我们已经实现了几个简单的 dataGener,代码在 expression/bench_test.go 中,可直接使用。 添加好 case 后,在 expression 目录下运行测试指令: # 功能测试 GO111MODULE=on go test -check.f TestVectorizedBuiltinMathFunc # 性能测试 go test -v -benchmem -bench=BenchmarkVectorizedBuiltinMathFunc -run=BenchmarkVectorizedBuiltinMathFunc 在你的 PR Description 中,请把性能测试结果附上。不同配置的机器,性能测试结果可能不同,我们对机器配置无任何要求,你只需在 PR 中带上你本地机器的测试结果,让我们对向量化前后的性能有一个对比即可。 如何成为 Contributor 为了推进表达式向量化计算,我们正式成立 Vectorized Expression Working Group,其具体的目标和制度详见 这里 。与此对应,我们在 TiDB Community Slack 中创建了 wg-vec-expr channel 供大家交流讨论,不设门槛,欢迎感兴趣的同学加入。 如何成为 Contributor: 在此 issue 内选择感兴趣的函数并告诉大家你会完成它; 为该函数实现 vecEvalXType() 和 vectorized() 的方法; 在向量化测试框架内添加对该函数的测试; 运行 make dev ,保证所有 test 都能通过; 发起 Pull Request 并完成 merge 到主分支。 如果贡献突出,可能被提名为 reviewer,reviewer 的介绍请看 这里 。 如果你有任何疑问,也欢迎到 wg-vec-expr channel 中提问和讨论。 原文阅读: https://pingcap.com/blog-cn/10mins-become-contributor-of-tidb-20190916/ 数据库 2019-09-17 14:06:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 平时用来测试的异常处理 我们都是通过dbms_output.put_line来输出异常信息,但是在实际的应用中,需要把异常信息返回给调用的客户端。 其实 RAISE_APPLICATION_ERROR 是将应用程序专有的错误从服务器端转达到客户端应用程序(其他机器上的SQLPLUS或者其他前台开发语言) raise_application_error(异常类型,传递信息) 异常类型:number 值域:-20000 到-20999 传递信息:varchar2(2000) DBMS_STANDARD包的RAISE_APPLICATION_ERROR过程,可以重新定义异常错误消息,它为应用程序提供了一种与ORACLE交互的方法。语法如下 RAISE_APPLICATION_ERROR(errorNumber,errorString) errorNumber是数值在-20000到-20999之间,errorString为自定义的错误信息。 如: update jobs set job_title = v_newJobTitle where job_id = v_jobid; if sql%notfound then RAISE_APPLICATION_ERROR(-20167,'update failure!'); end if; .......... 当在sqlpus中测试时,一旦没有要更新的行,则抛出这样的异常: ORA-20167: update failure! oracle的异常分为编译时异常(错误)和运行时异常,前者不能被处理,后者可以被处理。 我们主要讨论运行时异常。 异常类型: a、预定义异常 已命名的预定义异常有CURSOR_ALREADY_OPEN、INVALID_NUMBER、TOO_MANY_ROWS等 b、用户定义异常 c、已命名异常(已命名异常不能单独归为一类异常,但它有点特别,所以我将它单独罗列说明) 如果希望处理一个异常(被when子串处理),那么异常必须有一个名字,如TOO_MANY_ROWS; 数据库错误有数千个,但是只有不到25个是内建的已命名异常(这些异常都声明在standard包中); 要处理那些未命名的异常时,你可以将一个名字和一个错误号联系在一起,达到这个目的的语句是pragma exception_init语句; 抛出异常: a、通过pl/sql运行时引擎 当数据库或pl/sql在运行时发生错误时,一个异常被pl/sql运行时引擎自动抛出 b、使用raise语句 异常也可以通过raise语句抛出:raise exception_name; c、调用raise_application_error存储过程 处理异常&异常传播: a、一旦程序进入异常部分就不能再回到同一块的执行部分;当异常被处理后,控制返回到外层执行部分的下一条语句; b、如果有when others子串,则必须放置在最后面作为缺省处理器处理没有显式处理的异常; c、执行部分抛出的异常将首先传递到同一块的异常部分,如果在同一块的异常部分没有处理这个异常的处理器,那么异常将会传播到上一层的异常部分中,一直到最外层; d、异常被处理后如果你仍然希望它继续传播,可以在异常处理的最后执行不带参数的raise语句(raise语句将重新抛出出现的异常,允许它继续传播); --这是一个上面部分知识点的示例(伪代码)说明 declare ... user_define_exception exception; --用户定义异常 invalid_column_name exception; --补充说明:如果我们在程序块中使用了无效列名,会有括号中的错误提示(ORA-00904:invalid column name) --下面我们将这个异常代码号与我们自定义的异常进行关联,即为异常命名 pragma exception_init(invalid_column_name,-904); begin ... --raise user_define_exception; --可以显式引发异常 exception when TOO_MANY_ROWS then --预定义异常处理 ...; when user_define_exception then --用户定义异常处理 ...; when invalid_column_name then --PRAGMA EXCEPTION_INIT异常处理 ...; raise; --继续传播该异常 end; sqlcode和sqlerrm: a、另外一种处理数据库错误的方法是使用内建函数sqlcode和sqlerrm; b、sqlcode将返回现行数据库错误号,这些错误号中除了no_data_found是+100外其他都是负数; c、sqlerrm返回文本描述的错误信息; d、为了获得用户自定义异常返回的sqlerrm和sqlcode,你需要使用raise_application_error函数给自定义异常标注错误号 给自定义错误标注号码: a、raise_application_error内建函数用于抛出一个异常并给异常赋予一个错误号以及错误信息; b、自定义异常的缺省错误号是+1,缺省信息是user_defined_exception。来自未处理的异常的一般信息对于识别导致错误的原因没有帮助, c、raise_application_error函数能够在pl/sql程序块的执行部分和异常部分调用,显式抛出带特殊错误号的命名异常; d、使用语法:raise_application_error(error_no,error_message[,{true|| false}]); e、错误号的范围是-20,001到-20,999;错误信息是文本字符串,最多为2048字节;true和false表示是添加(true)进错误堆(error stack)还是覆盖(overwrite)错误堆(false)。缺省情况下是false。 数据库 2019-09-16 15:49:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 摘要 最近发现服务器磁盘空间不足,发现是数据库占用空间太大了,决定删一部分数据,释放一些空间。结果,发现删除数据之后,linux磁盘空间并没有释放,opimize 之后,依然没有释放。各种折腾之后才搞清楚,建立数据库的时候,使用的表空间是默认表空间,也就是所有的数据都会写入到 ibdata1中,这种情况删除表内容的数据并optimize是没有作用的,必须是单表独立文件才能优化空。 最后解决方法,备份所有表数据,删除1bdata1文件(这中间也做了一些尝试,差点数据库起不来了),设置 单表独立空间参数(innodb_file_per_table=1),重新导入数据,这之后,每一个表都是一个独立的文件,删除数据之后是可以用optimize优化的 顺带提一下分区表,也就是按照一定的逻辑分表规则(没有命中规则的插入会失败),将数据落入到不同的数据文件中,这样加载数据的时候可能会效率高一些,但是受一些索引文件大小的影响,分区表还是不能解决大数据问题。 以后有空把这篇博客补充完整。 经过 忽略_bak,原路径是 /var/lib/mysql innodb_file_per_table=1 数据库 2019-09-12 11:05:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 应用系统的更新发布在企业日常运维中是一件比较常见工作,有文件的备份替换,也会有数据库方面的更新操作。本文介绍如何通过一台装有sqlplus工具的中转机对不同应用的Oracle数据库进行自动化发布。 经常遇到使用PL/SQL图形化工具对Oracle数据库进行相关的更新操作,例如程序包、触发器、存储过程、视图以及表中的数据。如果是单用户对单台数据库更新少量的内容,这个操作还可以接受,如果数据库服务器比较多,并且要切换不同的用户去更新大量的内容,这种方式就会比较低效繁琐,面对这种场景,实现后台自动化更新就很有必要。 如何通过一台sqlplus中转机对不同的Oracle数据库在后台完成更新示意如下: 规范要求 按照上图示意在后台完成数据库的发布更新需要一定的规范支持,简单来讲就是要让sqlplus工具能很明确的获取到以下几点信息: 更新时用什么账号去连接哪台服务器的哪个实例? 账号对应的密码应该如何传递给sqlplus命令? 更新的是程序包、存储过程还是视图? 多个更新之间是否有前后依赖关系? 更新文件的命名规范 通过sqlplus命令去连接Oracle数据库完成一次更新需要账号、密码、Oracle服务器的IP地址、侦听的端口、实例名、更新文件所在的路径,用法如下: 其中账号、IP地址、端口、实例名属于可公开的信息,这一部分内容可以连同更新次序和更新类型一起组织到文件名称中 例如【次序_账号_IP_实例名_XXX.类型】,示例: 01_admin_1.1.1.1_insA_package.pck 密码和相关信息储存 通过sqlplus进行数据库更新时用到的相关信息在本例中是储存在sqlplus中转机上,只有root账号可以获取到,并且密码是以密文的形式储存,密码的密文储存在以下路径的文件中(文件名是账号的密文): .XXX/.IP地址/.账号的密文 ,数据库实例名和端口号储存在以下路径中的文件中: .YYY/.IP地址/.实例名 ,整个路径只有root账号可以访问。示例如下: 发布过程 更新文件相关规范已经确定好,发布过程可以使用编写好的脚本(shell或bat等)轮询执行要更新的文件,从sqlplus中转机依次将内容更新到对应的Oracle服务器。 本例结合 嘉为蓝鲸应用发布 这款基于蓝鲸平台的SaaS将数据库发布过程流程化,调用发布脚本实现定时或实时更新,具体情况见下图: 无需逐个登录Oracle服务器,来回切换不同账号,更新过程中的日志如下图所示: 其它说明 本例通过sqlplus发布Oracle更新,需要有以下几个前提: 账号和密码信息要提前录入到sqlplus中转机(务必确保账号安全) Oracle服务器相关信息(IP、端口、实例名)也需要提前录入到sqlplus中转机 更新文件中的语法和符号必须规范(例如行尾的“;”号,包头包体结束位置的“/”)等等 数据库、sqlplus客户端的编码尽量保持一致。 作者: 徐晗 文章到此结束了~ 想到中秋即将来临啦!有没有很期待呀~ 在此先预祝大家 中秋节快乐 ! 佳节好文 业务复杂、数据庞大、应用广怎办?了解下分布式事务的解决思路! 赣州银行增强科技创新,实现一键灾备切换 SaaS设计:自动化服务启停设计示例 这里有份选择云服务商的攻略,请查收… 如何设计大型集团一体化IT运维系统 数据库 2019-09-10 17:42:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> create table test(id number); create table audit_table(table_name varchar2(20),ins int,upd int,del int); create or replace trigger test_tri after insert or update or delete on test declare v_count int; begin select count(*) into v_count from audit_table where table_name='TEST'; if v_count=0 then insert into audit_table values( 'TEST',0,0,0); end if; case when insertin then update test set ins=ins+1 where table_name='TEST'; when updating then udpate test set upd=upd+1 where table_name='TEST'; when deleting then update test set del=del+1 where table_name='TEST'; end case; end; begin for i in 1..100 loop insert into test values(i); end loop; end; select * from audit_table; table_name ins upd del TEST 1 0 0 ===== alter trigger as: ===== create or replace trigger test_tri after insert or update or delete on test for each row declare v_count int; begin select count(*) into v_count from audit_table where table_name='TEST'; if v_count=0 then insert into audit_table values( 'TEST',0,0,0); end if; case when insertin then update test set ins=ins+1 where table_name='TEST'; when updating then udpate test set upd=upd+1 where table_name='TEST'; when deleting then update test set del=del+1 where table_name='TEST'; end case; end; truncate audit_table; table has been truncated. truncate test; table has been truncated. begin for i in 1..100 loop insert into test values(i); end loop; end; select * from audit_table; table_name ins upd del TEST 100 0 0 数据库 2019-09-05 16:34:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> SELECT * FROM 表名 t WHERE IF (t.年龄>18,t.性别='M',1=1) AND t.性别='F' 数据库 2019-08-30 11:34:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 在现实的开发中,我们很少用到让MySQL自己生成uuid,因为在高并发场景下,这是不被允许的。通常是在代码中生成id,或者是使用专业的id服务器( Twitter-Snowflake )。我们要讨论的内容是,当我们在手动输入元数据的时候,如果恰巧有一列uuid,我们不想手动输入,而是希望MySQL为我们自动创建,那么我们可以使用触发器。 DELIMITER ;; CREATE TRIGGER `foo_before_insert` BEFORE INSERT ON `foo` FOR EACH ROW BEGIN IF new.id IS NULL THEN SET new.id = uuid(); END IF; END;; DELIMITER ; 最后,希望您谨慎地使用触发器、视图、外键等等,它们都会影响MySQL的性能。 本文的sql来自: MySQL set default id UUID 数据库 2019-08-30 10:37:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 8月28日,腾讯云数据库在京正式启动战略升级,宣布未来将聚焦云原生、自治、超融合三大战略方向,以用户为中心,联接未来。并在现场面向全球用户同步发布五大战略级新品,包括数据库智能管家DBbrain、云数据库TBase、数据库备份服务DBS、云数据库Redis混合存储版,以及自研云原生数据库CynosDB商业化版本。 战略聚焦三大主航道,推进百万企业全面上云 作为企业IT的核心系统之一,数据库市场正在面临根本性变革。在全面上云的大趋势下,传统的数据库上云模式逐渐无法满足客户业务的快速扩展和智能运维需求。客户需要的是一套能够灵活扩展、智能诊断,支持跨云融合的新一代云端原生数据库系统,未来数据库发展方向将从“数据库+云”模式全面转向“云+数据库”模式。 基于这样的判断,腾讯云数据库的未来将战略聚焦云原生、自治、超融合三大主航道,完善自身产品矩阵。让融合了云与AI能力的数据库变得更智能、稳定、可靠、安全、便宜,推进百万企业全面“上云”进程。 腾讯云数据库产品总监王义成表示:“全球数据库的发展即将进入下一战场,以腾讯云为代表的云厂商,基于在云计算、大数据以及人工智能领域的规模和技术积累,在这一轮技术变革中将具备众多先天优势。有鉴于此,腾讯云数据库充分整合多年服务各行各业的成功经验,推出多款能够真正满足用户需求的数据库产品,助力企业快速数字化、智能化转型。” 重磅发布五大战略级新品,布局未来数据库场景 云原生赛道,腾讯云宣布自研新一代企业级分布式数据库CynosDB正式商业化。不同于过去云数据库在传统数据库之上扩展一部分云的能力,CynosDB是纯粹的云原生数据库,融合了传统数据库、云计算和新硬件的优势,支持海量存储、百万级查询和秒级的故障恢复,100%兼容MySQL和PostgreSQL,提供更智能的运维管理和更可靠的安全保障。与高性能形成对比的是,CynosDB价格仅为市面上商业数据库的1/15,极大降低了企业“上云”成本。 数据库自治领域,腾讯云结合前沿的人工智能技术推出了数据库智能管家DBbrain。它将大量数据库问题的诊断优化工作自动化、智能化和可视化,利用机器学习、大数据技术快速学习资深数据库管理员的成熟经验,服务于云上和云下企业,构建一套“会说话”的数据库服务系统。作为一款数据库智能诊断和优化产品,DBbrain为用户提供实时的性能诊断和安全防护,高效的帮助用户定位故障原因、优化建议、协助用户从源头进行预防,并通过AI调参能力,提升数据库整体性能。 超融合领域,腾讯云发布云数据库TBase及数据库备份服务DBS,并启动了腾讯云Redis混合存储版邀约测试。 详细来说,TBase是腾讯自主研发的分布式国产数据库,提供领先的HTAP能力,在提供NewSQL便利性的同时完整支持分布式事务并保持SQL兼容性,支持RR、RC、SSI三种隔离级别,同时兼容Oracle语法。对于日益多元化的企业客户,TBase满足了他们对业务融合、场景融合、管理融合的更高诉求。强大的安全和容灾能力,让TBase已经成功应用在腾讯内部的微信支付,以及外部众多金融、政府、电信、医疗等行业的核心业务系统。 数据库备份DBS拥有一套完整的数据备份和数据恢复解决方案,具备实时备份和秒级的数据恢复能力,可以为公有云及混合云环境下的用户数据库提供强有力的容灾服务。该产品的推出,有望让“光缆挖断”导致业务停摆成为历史,最大程度的降低非可控因素比如地震、火灾、海啸、甚至挖掘机等对业务造成的影响。 云数据库Redis混合存储版本是腾讯云自主研发的,100%兼容Redis协议和数据结构,具备自动降冷能力的版本。产品特性上,Redis混合存储版支持所有数据存储到磁盘,热数据自动缓存,冷数据自动落盘,能够显著降低客户运营成本,提高研发效率。目前,该产品最大提供36TB存储规格。 产品家族进一步丰富,增速连续两年全球前三 随着战略定位的进一步聚焦以及众多新产品的推出,腾讯云数据库产品家族将进一步丰富,企业上云不仅更为方便,成本也会越来越低。截止目前,腾讯云数据库服务涵盖总计20多种数据库服务。同时,还在以每年发布5大产品、50多个新功能的速度递增。 腾讯云数据库产品线涵盖了业内主流的数据库产品,包括开源数据库MySQL、MariaDB、MongoDB、Redis;商业数据库Oracle、SQL Server;自研数据库TDSQL、TBase以及云原生数据库CynosDB。同时,随着5G时代的到来,针对物联网、大数据等海量时序数据的场景,腾讯云推出时序数据库CTSDB。除此之外,腾讯云也已经启动图数据库等新型数据库领域的开发工作。 今年以来,腾讯云数据库先后获得Forrester以及Gartner等权威机构的一致认可。在6月份,腾讯云数据库被Forrester评为全球数据库领域 “实力竞争者” ,同时,Gartner报告也显示,2018年腾讯云数据库市场份额增速达123%,位列国内所有数据库厂商之首,在全球范围内保持了连续两年增速前三的迅猛势头。 未来,腾讯云数据库将深耕云原生、自治、超融合三大战场,以 “云+数据库” 新模式助力产业腾飞,为各行业用户数字化转型助力! 数据库 2019-08-29 10:51:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 数据库的高可用是指最大程度地为用户提供服务,避免服务器宕机等故障带来的服务中断。数据库的高可用性不仅仅体现在数据库能否持续提供服务,而且也体现在能否保证数据的一致性。 SequoiaDB 巨杉数据库作为一款100%兼容 MySQL 的国产开源分布式数据库,它在高可用方面的表现如何?它的高可用性是如何实现的?本文将详细描述SequoiaDB巨杉数据库的高可用性原理,并进行测试验证。 01 巨杉分布式集群架构 SequoiaDB 巨杉数据库采用计算与存储分离架构,SequoiaSQL-MySQL 是 SQL 计算层,存储层由协调节点、编目节点和数据节点组成。 图1 SequoiaDB分布式架构 如图1所示是最简单的 SequoiaDB 分布式数据库集群架构图,由1个协调节点,1个编目节点,3个数据节点和 SequoiaSQL-MySQL 构成。其中数据节点在三个服务器上,包括三个数据复制组1、2、3,每个数据复制组由3个完全相同的数据副本组成,数据副本之间通过日志同步保持数据一致。 A, A1, A2组成数据复制组1,三者是完全相同数据副本。数据复制组2、3类似于数据复制组1。在 SequoiaDB 分布式集群中,每个复制组最多支持 7 个数据副本。 本文的高可用测试环境采用图1所示的分布式集群架构,其中主节点有读写功能,两个备副本可以执行读操作或备份。 02 巨杉数据库高可用实现 SequoiaDB 高可用采用 Raft 算法实现,多副本之间通过日志同步保持数据一致性。 图2 三个节点之间保持连接 如图2所示,SequoiaDB 集群三个副本之间通过心跳保持连接。 数据组副本之间通过共享心跳信息 sharing-beat 进行状态共享。如图3所示,sharing-beat 心跳信息结构包括心跳 ID、自身开始LSN、自身终止LSN、时间戳、数据组版本号、自身当前的角色和同步状态。 图3 心跳状态信息结构 每个节点都维护一张 status-sharing table 表,用来记录节点状态。sharing-beat 每2秒发送一次,采集应答信息,若连续N秒未收到应答信息,则认为节点宕机。 集群中只有一个节点作为主节点,其他节点为备节点。如果出现多主或者双主,需要根据 LSN 对比进行降备,保证集群中只有一个主节点。 Note: 1)当主节点宕机时,需要从备节点中选举出一个新的节点作为新的主节点。 2)当备节点宕机时,主节点不受影响,等备节点恢复后,通过日志同步继续与主节点保持数据一致即可。 下面介绍当主节点宕机时,选举新主节点的过程。 选举条件 满足下面2个条件可以被选举成为主节点: 1. 多数备节点投票通过 2. 该节点LSN最大 选举过程 1)当主节点A宕机时,A自动降为备节点,关闭协调节点的业务连接。 图4 集群中主节点挂掉 2)A1和A2都会判断自身是否具备升为主节点的条件,若符合即发起选举请求。 条件内容: 自己不是主节点 剩下的备节点占半数以上 自己的LSN比其它备节点的LSN新 3)其它备节点会把被投票节点的 LSN 与自己的 LSN 做对比,若比自己的 LSN 新,则投赞成票,否则投反对票。 4)若赞成票超过(n/2+1),则支持该节点为主节点,选举成功。否则保持备节点角色,选举失败。 5)选举成功后,通过心跳状态信息共享数据组信息给其它节点。 03 高可用容灾验证 一般分布式数据库 POC 测试包含功能测试、性能测试、分布式事务测试、高可用容灾测试和兼容性测试等。下面将对 SequoiaDB 巨杉数据库的高可用性进行验证测试。 测试环境说明 本文测试环境采用分布式集群,包含1个 SequoiaSQL-MySQL,3个数据节点,1个编目节点,1个协调节点,搭建集群方式具体可参考巨杉官网虚拟机镜像搭建教程。在 kill 掉主节点进程之后,我们对分布式数据库集群进行读写操作,来验证高可用性。 查看服务器集群状态 # service sdbcm status ..... Main PID: 803 (sdbcm) Tasks: 205 (limit: 2319) CGroup: /system.slice/sdbcm.service ├─ 779 sdbcmd ├─ 803 sdbcm(11790) ├─1166 sequoiadb(11840) D ├─1169 sequoiadb(11810) S ├─1172 sequoiadb(11830) D ├─1175 sdbom(11780) ├─1178 sequoiadb(11820) D ├─1181 sequoiadb(11800) C 1369 /opt/sequoiadb/plugins/SequoiaSQL/bin/../../../java/jdk/bin/java -jar /opt/sequoiadb/plugins/SequoiaSQL ..... SequoiaDB 分布式集群中数据节点端口在11820,11830,11840;编目节点11800,协调节点在11810 sdbadmin @sequoiadb :~$ ps -ef|grep sequoiadb sdbadmin 1166 1 0 Aug20 ? 00:02:23 sequoiadb(11840) D sdbadmin 1169 1 0 Aug20 ? 00:01:43 sequoiadb(11810) S sdbadmin 1172 1 0 Aug20 ? 00:02:24 sequoiadb(11830) D sdbadmin 1178 1 0 Aug20 ? 00:02:33 sequoiadb(11820) D sdbadmin 1181 1 0 Aug20 ? 00:04:01 sequoiadb(11800) C kill 掉11820的主节点,执行查询和写入sql sdbadmin @sequoiadb :~$ kill 1178 sdbadmin @sequoiadb :~$ ps -ef|grep sequoiadb sdbadmin 1166 1 0 Aug20 ? 00:02:24 sequoiadb(11840) D sdbadmin 1169 1 0 Aug20 ? 00:01:43 sequoiadb(11810) S sdbadmin 1172 1 0 Aug20 ? 00:02:24 sequoiadb(11830) D sdbadmin 1181 1 0 Aug20 ? 00:04:01 sequoiadb(11800) C sdbadmin 1369 1 0 Aug20 ? 00:01:33 /opt/sequoiadb .... 执行查看 sql,查看插入操作之前数据为121 mysql> select * from news.user_info; +------+-----------+ | id | unickname | +------+-----------+ | 1 | test1 | ........ | 119 | test119 | | 120 | test120 | | 121 | test121 | +------+-----------+ 121 rows in set (0.01 sec) 执行写入 sql,查看插入是否成功 mysql> insert into news.user_info(id,unickname)values(122,"s uccess"); Query OK, 1 row affected (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.01 sec) mysql> select * from news.user_info; +------+-----------+ | id | unickname | +------+-----------+ | 1 | test1 | ......... | 120 | test120 | | 121 | test121 | | 122 | success | +------+-----------+ 122 rows in set (0.00 sec) 数据(122, “success”)数据插入成功,在其中一个主节点挂掉情况下,读写都没有受到影响,数据读写保持一致,高可用性得到验证。 现在执行导入1000w数据写入脚本 imprt.sh,在执行过程中 kill 掉主数据节点,模拟主节点故障场景,在巨杉数据库图形化监控界面 SAC 上查看集群读写变化。 Note: 如果需要获取 imprt.sh 脚本,关注“巨杉数据库”公众号回复 “imprt” 即可获取。 执行导入数据脚本 ./imprt.sh 协调节点主机 协调节点端⼝ 次数 ./imprt.sh 192.168.1.122 11810 100 如图5所示,在执行导入数据时刻,kill 掉主数据节点,insert 写入下降,之后集群恢复高可用 图5 SAC监控界面集群读写变化示意图 图6 SAC查看tpcc写入数据量示意图 从 SAC 可视化界面中可以看到,当主数据节点在我们执行插入1000w数据操作的过程中出现故障,数据读写受到影响的持续时间很短。最后通过使用 imprt.sh 脚本重新导入插入失败的数据,则可以保证数据最终一致性。 04 总结 SequoiaDB 分布式集群具备较好的高可用性,集群可以设置多个数据复制组,每个数据复制组由多个完全相同的副本构成,副本之间通过 Raft 算法和日志同步方式保持数据一致性。最后,本文也验证了在执行千万级数据写操作时,若集群主数据节点宕机,分布式集群可以正常读写数据,并且数据保持最终一致,高可用性得到验证。 数据库 2019-08-28 11:55:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 表结构: 姓名 课程 分数 张三 | 语文 | 74 |
姓名 语文 数学 物理 平均分 总分 张三 李四 | 74 74 | 83 84 | 93 94 | 83.33 84.00 | 250 252 | sql实现: SELECT t.student AS '姓名', max( CASE WHEN course_name = '语文' THEN '分数' ELSE 0 END ) AS '语文', max( CASE WHEN course_name = '数学' THEN '分数' ELSE 0 END ) AS '数学', max( CASE WHEN course_name = '物理 ' THEN '分数' ELSE 0 END ) AS '物理 ', cast(avg(t.score) as decimal(18,2)) AS '平均分', sum(t.score) AS '总分' FROM course t GROUP BY t.student 数据库 2019-08-19 10:35:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 转发: https://blog.csdn.net/zuozewei/article/details/82911173 借鉴: https://testerhome.com/topics/16548 唯一需要修改的是: 数据库 2019-07-31 09:51:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 原创: 陈俊聪 背景 很神奇,5.7.17 和 8.0.17,连续两个17小版本都让人眼前一亮。前者加入了组复制(Group Replication)功能,后者加入了克隆插件(Clone Plugin)功能。今天我们实战测试一下这个新功能。 克隆插件简介 克隆插件允许在本地或从远程 MySQL 实例克隆数据。克隆数据是存储在 InnoDB 其中的数据的物理快照,其中包括库、表、表空间和数据字典元数据。克隆的数据包含一个功能齐全的数据目录,允许使用克隆插件进行 MySQL 服务器配置。 克隆插件支持两种克隆方式 本地克隆 远程克隆 本地克隆 本地克隆操作将启动克隆操作的 MySQL 服务器实例中的数据克隆到同服务器或同节点上的一个目录里 远程克隆 默认情况下,远程克隆操作会删除接受者(recipient)数据目录中的数据,并将其替换为捐赠者(donor)的克隆数据。(可选)您也可以将数据克隆到接受者的其他目录,以避免删除现有数据。 远程克隆操作和本地克隆操作克隆的数据没有区别,数据是相同的。 克隆插件支持复制。除克隆数据外,克隆操作还从捐赠者中提取并传输复制位置信息,并将其应用于接受者,从而可以使用克隆插件来配置组复制或主从复制。使用克隆插件进行配置比复制大量事务要快得多,效率更高。 实战部分 一、本地克隆 安装克隆插件 启动前 [mysqld] plugin-load-add=mysql_clone.so 或运行中 INSTALL PLUGIN clone SONAME 'mysql_clone.so'; | 第二种方法会注册到元数据,所以不用担心重启插件会失效。两种方法都很好用 检查插件有没有启用 mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'clone'; +-------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +-------------+---------------+ | clone | ACTIVE | +-------------+---------------+ 1 row in set (0.01 sec) 设置强制启动失败参数 [mysqld] plugin-load-add=mysql_clone.so clone=FORCE_PLUS_PERMANENT | 如果克隆插件对你们很重要,可以设置clone=FORCE_PLUS_PERMANENT或clone=FORCE。作用是:如果插件未成功初始化,就会强制mysqld启动失败。 克隆需要的权限 需要有备份锁的权限。备份锁是 MySQL 8.0 的新特性之一,比5.7版本的flush table with read lock要轻量。 mysql> CREATE USER clone_user@'%' IDENTIFIED by 'password'; mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user'; # BACKUP_ADMIN是MySQL8.0 才有的备份锁的权限 执行本地克隆 mysql -uclone_user -ppassword -S /tmp/mysql3008.sock mysql> CLONE LOCAL DATA DIRECTORY = '/fander/clone_dir'; | 例子中需要 MySQL 的运行用户拥有 fander 目录的rwx权限,要求 clone_dir 目录不存在 本地克隆的步骤如下 DROP DATA FILE COPY PAGE COPY REDO COPY FILE SYNC 观察方法如下 mysql> SELECT STAGE, STATE, END_TIME FROM performance_schema.clone_progress; +-----------+-------------+----------------------------+ | STAGE | STATE | END_TIME | +-----------+-------------+----------------------------+ | DROP DATA | Completed | 2019-07-25 21:00:18.858471 | | FILE COPY | Completed | 2019-07-25 21:00:19.071174 | | PAGE COPY | Completed | 2019-07-25 21:00:19.075325 | | REDO COPY | Completed | 2019-07-25 21:00:19.076661 | | FILE SYNC | Completed | 2019-07-25 21:00:19.168961 | | RESTART | Not Started | NULL | | RECOVERY | Not Started | NULL | +-----------+-------------+----------------------------+ 7 rows in set (0.00 sec) 当然还有另外一个观察方法 mysql> set global log_error_verbosity=3; Query OK, 0 rows affected (0.00 sec) mysql> CLONE LOCAL DATA DIRECTORY = '/fander/clone6_dir'; Query OK, 0 rows affected (0.24 sec) [root@192-168-199-101 data]# tailf mysql-error.err 2019-07-25T22:22:58.261861+08:00 8 [Note] [MY-013457] [InnoDB] Clone Begin Master Task by root@localhost 2019-07-25T22:22:58.262422+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply Master Loop Back 2019-07-25T22:22:58.262523+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply Begin Master Task ... 2019-07-25T22:22:58.471108+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State FLUSH DATA: 2019-07-25T22:22:58.472178+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State FLUSH REDO: 2019-07-25T22:22:58.506488+08:00 8 [Note] [MY-013458] [InnoDB] Clone Apply State DONE 2019-07-25T22:22:58.506676+08:00 8 [Note] [MY-013457] [InnoDB] Clone Apply End Master Task ID: 0 Passed, code: 0: 2019-07-25T22:22:58.506707+08:00 8 [Note] [MY-013457] [InnoDB] Clone End Master Task ID: 0 Passed, code: 0: 测试,起一个克隆的实例 /opt/mysql8.0/bin/mysqld --datadir=/fander/clone_dir --port=3333 --socket=/tmp/mysql3333.sock --user=mysql3008user --lower-case-table-names=1 --mysqlx=OFF #解释,因为我没有使用my.cnf,所以加了比较多参数 #--datadir 指定启动的数据目录 #--port 指定启动的MySQL监听端口 #--socket 指定socket路径 #--user `捐赠者`的目录权限是mysql3008user:mysql3008user,用户也是mysql3008user,我没有修改 #--lower-case-table-names=1 同`捐赠者` #--mysqlx=OFF 不关闭的话,默认mysqlx端口会合`捐赠者`的33060重复冲突 #登录检查 mysql -uroot -proot -S /tmp/mysql3333.sock mysql> show master status\G # 可见GTID是`捐赠者`的子集,所以说明`接受者`直接和`捐赠者`建主从复制是很简单的 二、远程克隆 远程克隆的前提条件和限制 捐赠者和接受者都需要安装克隆插件 捐赠者和接受者分别需要有至少BACKUP_ADMIN/CLONE_ADMIN权限的账号 | 暗示了接受者必须先启动一个数据库实例(空或有数据的实例均可,因为都会被删除) 克隆目标目录必须有写入权限 克隆操作期间不允许使用 DDL,允许并发DML。要求相同版本号,您无法MySQL 5.7和MySQL 8.0之间进行克隆,而且要求版本>=8.0.17 同一平台同一架构,例如linux to windows、x64 to x32 是不支持。 足够的磁盘空间 可以克隆操作一般表空间,但必须要有目录权限,不支持克隆使用绝对路径创建的一般空间。与源表空间文件具有相同路径的克隆表空间文件将导致冲突 远程克隆时不支持CLONE INSTANCE FROM中通过使用mysqlx的端口 克隆插件不支持克隆MySQL服务器配置my.cnf等 克隆插件不支持克隆二进制日志。 克隆插件仅克隆存储的数据 InnoDB。不克隆其他存储引擎数据。MyISAM并且 CSV存储在包括sys模式的任何模式中的表都被克隆为空表。 不支持通过MySQL router连接到捐赠者实例。 一些参数是必须一致的,例如innodb_page_size、innodb_data_file_path、--lower_case_table_ names 如果克隆加密或页面压缩数据,则捐赠者和接收者必须具有相同的文件系统块大小 如果要克隆加密数据,则需要安全连接 clone_valid_donor_list 在接受者的设置必须包含捐赠者 MySQL 服务器实例的主机地址。 必须没有其他克隆操作正在运行。一次只允许一次克隆操作。要确定克隆操作是否正在运行,请查询该 clone_status表。 默认情况下,克隆数据后会自动重新启动接受者 MySQL 实例。要自动重新启动,必须在接收方上提供监视进程以检测服务器是否已关闭。否则,在克隆数据后,克隆操作将停止并出现以下错误,并且关闭接受者 MySQL 服务器实例: | 此错误不表示克隆失败。这意味着必须在克隆数据后手动重新启动接受者的 MySQL 实例。 远程克隆实战 假设前提条件都满足,步骤如下 和本地克隆一样,远程克隆需要插件安装和用户授权。捐赠者、接受者的授权略有不同。 1. 确保捐赠者和接受者都安装了克隆插件 INSTALL PLUGIN clone SONAME 'mysql_clone.so'; 2. 用户账号授权 捐赠者授权 mysql> CREATE USER clone_user@'192.168.199.101' IDENTIFIED by 'password1'; mysql> GRANT BACKUP_ADMIN ON *.* TO 'clone_user'@'192.168.199.101'; # BACKUP_ADMIN是MySQL8.0 才有的备份锁的权限 接受者授权 mysql> CREATE USER clone_user@'192.168.199.102' IDENTIFIED by 'password2'; mysql> GRANT CLONE_ADMIN ON *.* TO 'clone_user'@'192.168.199.102'; | CLONE_ADMIN权限 = BACKUP_ADMIN权限 + SHUTDOWN权限。SHUTDOWN仅限允许用户shutdown和restart mysqld。授权不同是因为,接受者需要restart mysqld。 3. 接受者设置捐赠者列表清单 mysql -uclone_user -ppassword2 -h192.168.199.102 -P3008 mysql> SET GLOBAL clone_valid_donor_list = '192.168.199.101:3008'; | 这看起来是一个安全相关参数。多个实例用逗号分隔,例如“HOST1:PORT1,HOST2:PORT2,HOST3:PORT3” 接受者开始拉取克隆捐赠者数据 CLONE INSTANCE FROM clone_user@'192.168.199.101':3008 IDENTIFIED BY 'password1'; 远程克隆步骤如下 mysql> SELECT STAGE, STATE, END_TIME FROM performance_schema.clone_progress; +-----------+-----------+----------------------------+ | STAGE | STATE | END_TIME | +-----------+-----------+----------------------------+ | DROP DATA | Completed | 2019-07-25 21:56:01.725783 | | FILE COPY | Completed | 2019-07-25 21:56:02.228686 | | PAGE COPY | Completed | 2019-07-25 21:56:02.331409 | | REDO COPY | Completed | 2019-07-25 21:56:02.432468 | | FILE SYNC | Completed | 2019-07-25 21:56:02.576936 | | RESTART | Completed | 2019-07-25 21:56:06.564090 | | RECOVERY | Completed | 2019-07-25 21:56:06.892049 | +-----------+-----------+----------------------------+ 7 rows in set (0.01 sec) 接受者如果非mysqld_safe启动的,会报错误,但不影响克隆,需要您人手启动mysqld即可。 ERROR 3707 (HY000): Restart server failed (mysqld is not managed by supervisor process). 实操后小结:克隆与xtrabackup的对比 克隆和xtrabackup备份都属于物理热备,备份恢复原理也近似。 克隆在恢复实例时需要先启动一个实例并授权,而xtrabackup不需要。 xtrabackup在backup后需要apply log,克隆是类似mysqlbackup提供的backup-and-apply-log,合并在一起做。 xtrabackup备份文件的权限等于执行命令的人的权限,恢复实例时需要人手chown回实例权限,克隆备份后权限和原数据权限一致,无需再人手chown,方便恢复。 xtrabackup恢复时需要在mysql中执行reset master;然后set global gtid_purged="UUID:NUMBER",具体的UUID:NUMBER的值为备份文件中的xtrabackup_info文件的内容;克隆不需要这个操作步骤,默认克隆完就可以建立复制了。 xtrabackup备份完一般是scp拷贝到另外一台机器恢复,走的是22端口;克隆走的是MySQL的监听端口。所以在目录权限正确的情况下,甚至根本不需要登录Linux服务器的权限。如下: [root@192-168-199-103 ~]# mysql -uroot -ppassword2 -h192.168.199.102 -P3008 -e "SET GLOBAL clone_valid_donor_list = '192.168.199.101:3008';" mysql: [Warning] Using a password on the command line interface can be insecure. [root@192-168-199-103 ~]# mysql -uroot -ppassword2 -h192.168.199.102 -P3008 -e "CLONE INSTANCE FROM root@'192.168.199.101':3008 IDENTIFIED BY 'password1';" mysql: [Warning] Using a password on the command line interface can be insecure. 三、利用克隆建立主从复制 克隆出来的接受者实例,可以与捐赠者建立主从复制。当然建立组复制也是可以的,鉴于篇幅的原因,不做示例有兴趣可以阅读官方文档18.4.3.1节“克隆分布式恢复”。 | https://dev.mysql.com/doc/refman/8.0/en/group-replication-cloning.html 传统复制时,通过以下命令查看postion位置 mysql> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status; +------------------+-----------------+ | BINLOG_FILE | BINLOG_POSITION | +------------------+-----------------+ | mysql-bin.000014 | 2179 | +------------------+-----------------+ 1 row in set (0.01 sec) GTID复制时,通过以下命令查看GTID位置 mysql> SELECT @@GLOBAL.GTID_EXECUTED; +-------------------------------------------+ | @@GLOBAL.GTID_EXECUTED | +-------------------------------------------+ | 990fa9a4-7aca-11e9-89fa-000c29abbade:1-11 | +-------------------------------------------+ 1 row in set (0.00 sec) 假设已经有如下授权,我们就可以建立复制啦 create user repl@'%' identified WITH 'mysql_native_password' by 'password'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'%'; 建立GTID主从复制关系 (接受者上) CHANGE MASTER TO MASTER_HOST='192.168.199.101', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_PORT=3008, MASTER_AUTO_POSITION=1; 监控克隆操作 检查克隆进度 mysql> SELECT STATE FROM performance_schema.clone_status; +-----------+ | STATE | +-----------+ | Completed | +-----------+ 1 row in set (0.00 sec) SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status; 检查克隆是否出错 mysql> SELECT STATE, ERROR_NO, ERROR_MESSAGE FROM performance_schema.clone_status; +-----------+----------+---------------+ | STATE | ERROR_NO | ERROR_MESSAGE | +-----------+----------+---------------+ | Completed | 0 | | +-----------+----------+---------------+ 1 row in set (0.00 sec) 检查克隆次数 show global status like 'Com_clone'; # `捐赠者` 每次+1,`接受者` 0 随时可以kill掉克隆 使用 SELECT * FROM performance_schema.clone_status\G 或 show processlist 查看线程ID,然后kill ID 总结 克隆功能非常有趣。他操作简单,可以用于快速搭建、恢复主从复制或组复制,可以部分取代开源热备软件xtrabackup,期待未来官方会把他做得越来越好,功能越来越丰富。 数据库 2019-07-29 11:00:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 安装Oracle 11g后,共有7个服务,这七个服务的含义分别为: 1. Oracle ORCL VSS Writer Service:Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Service)能够让存储基础设备(比如磁盘,阵列等)创建高保真的时间点映像,即映射拷贝(shadow copy)。它可以在多卷或者单个卷上创建映射拷贝,同时不会影响到系统的系统能。(非必须启动) 2. OracleDBConsoleorcl:Oracle数据库控制台服务,orcl是Oracle的实例标识,默认的实例为orcl。在运行Enterprise Manager(企业管理器OEM)的时候,需要启动这个服务。(非必须启动) 3. OracleJobSchedulerORCL:Oracle作业调度(定时器)服务,ORCL是Oracle实例标识。(非必须启动) 4. OracleMTSRecoveryService:服务端控制。该服务允许数据库充当一个微软事务服务器MTS、COM/COM+对象和分布式环境下的事务的资源管理器。(非必须启动) 5. OracleOraDb11g_home1ClrAgent:Oracle数据库.NET扩展服务的一部分。 (非必须启动) 6. OracleOraDb11g_home1TNSListener:监听器服务,服务只有在数据库需要远程访问的时候才需要。(非必须启动,下面会有详细详解)。 7. OracleServiceORCL:数据库服务(数据库实例),是Oracle核心服务该服务,是数据库启动的基础, 只有该服务启动,Oracle数据库才能正常启动。(必须启动) 那么在开发的时候到底需要启动哪些服务呢? 对新手来说,要是只用Oracle自带的sql*plus的话,只要启动OracleServiceORCL即可,要是使用PL/SQL Developer等第三方工具的话,OracleOraDb11g_home1TNSListener服务也要开启。OracleDBConsoleorcl是进入基于web的EM必须开启的,其余服务很少用。 注:ORCL是数据库实例名,默认的数据库是ORCL,你可以创建其他的,即OracleService+数据库名。 数据库 2019-07-25 17:20:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> Nebula Graph :一个开源的分布式图数据库。作为唯一能够存储万亿个带属性的节点和边的在线图数据库,Nebula Graph 不仅能够在高并发场景下满足毫秒级的低时延查询要求,还能够实现服务高可用且保障数据安全性。 本篇导读 HBaseCon Asia2019 活动于 2019 年 7 月 20 日于北京金隅喜来登酒店举办,应主办方邀请,Nebula Graph 技术总监-陈恒在活动中发表演讲 “Nebula: A Graph DB based on HBase” 。本篇文章是根据此次演讲所整理出的技术干货,全文阅读需要 30 分钟。 大家下午好,我是陈恒,来自 VESoft,是开源图数据库 Nebula Graph 的开发者。同时,我也是 HBase 的 Commiter Nebula Graph 简要介绍 首先,介绍一下我们公司:欧若数网科技有限公司(英文名:VESoft),是 2018 年 10 月份成立的。我们的核心产品是分布式图数据库 Nebula Graph,这个项目从开始到现在,大概做了半年多时间。目前已经 release alpha 版本,还有可以试用的 docker,正式的 release 预计会在 10 月份。 NebulaGraph 是完全开源的,可以在 GitHub 上访问 https://www.github.com/vesoft-inc/Nebula NoSQL 类数据库的发展趋势 下面我们看一张图,是 DB-Engine 的统计,反映了从 2013 年到今年所有的 NoSQL 类数据库的发展趋势。横轴代表的是时间,纵轴可以认为是受众程度,或者社区里的讨论热烈程度。大家可以看到绿色的线就是图数据库。这些年一共翻了十倍,增长还是非常迅猛的。 图数据库的简要介绍 在座的同事是 HBase 专家,部分可能对于图数据库有些不太了解,我这里简单介绍一下图数据库。它的主要应用场景其实是针对于各种各样的点和边组成的数据集合。 图数据库典型应用场景 举几个例子来讲,典型图数据库的应用场景有以下几个。 社交场景 社交场景是一个我们常见的社交场景,就是好友之间的关系。这个自然而然构成了一张图。比如说:在社交场景里面,做推荐算法。为某个人推荐他的好友。现在典型的方法都是去找好友的好友,然后看好友的好友有没有可能成为新的好友。这里面可能会有各种亲密度关系,以及各种各样的排序。传统来讲,我们可能会利用 MySQL 或者是 HBase 存各种各样的好友关系,然后通过多个 串行的 Key Value 访问来查 。但是真正在线上场景里面的话,是很难满足性能要求的。所以,另外一种做法是利用 离线计算 。把可能的好友关联和推荐都离线计算好。然后,查的时候直接去读已经准备好的数据,但这个问题就在于时效性比较差。对于有一些对于时效性要求比较高的场景,这样是不可以接受的。后面我有一些 case 可以来谈这个事情。 商业关系网络 商业关系网络:数据库的使用场景除了社交网络外,还有商业关系网络也很常见。在金融和风控领域,商业关系其实是很典型的一张图,多个公司之间有贸易往来,公司和银行之间也有往来。比如说一个公司去银行申请贷null款的时候,银行在审查这家公司可能本身没有什么问题,但是这家公司可能控制或者被控制的其他公司,或者整个集团的其他子公司,早已经进入了黑名单,甚至要控制一组相互担保的公司之间的总体贷款额度。这个时候就需要构成一些风控的功能来拒掉这笔贷款。商业关系里面还有人与人之间的转账关系,比如去查一个信用卡反套null现的网络。很典型的一个网络社群就是:A 转账到 B,B 转账到 C,C 又转让回 A 就是一个很典型的一个环。更多的黑产可能会是一个很大的黑产社区。对于这样的闭环,这类查询在图数据库大规模应用之前,大部分都是采用离线计算的方式去找。但是离线场景很难去控制当前发生的这笔交易。例如一个信用卡交易或者在线贷null款,整个作业流程很长,在反套null现这块的审核时间可能只有秒级。这也是图数据库非常大的一个应用场景。 知识图谱 知识图谱:除了商业关系还有一个就是知识图谱。知识图谱这个概念提出来已经很早了,大概是在 2004,2005 年的时候,Google 把自己的 search engine 慢慢的从倒排转到知识图谱上。这样在 search 的时候可以回答一些问题,比如说今天的天气怎么样?比如说现在谁的老婆的外甥的二大爷是谁。根据一些类似于问题式的知识,而不是基于关键字进行 search。知识图谱这几年非常的火,主要的原因就是一些垂直领域,慢慢的发现知识图谱非常的有价值。比如说:在金融领域上会有自己金融领域的知识图谱,结合一些 NLP 技术做大量的财报自动分析,或者像 Kensho 这样的新闻事件驱动自动生成分析报表和投资建议;还可以做一些投资组合,发现一二级市场公司内的关联关系,财务造假或者地方债暴雷造成的风险传播。再比如很多做在线教育的同事可能知道,在线教育的领域里面也有不少知识图谱。比如说有哪些考点,这个题是属于哪些考点,考点之间是怎么关联起来的,做错的考点附近的知识点都需要加强,这样也是一张关系网络。也是图数据库一个广泛应用的场景。 IoT 物联网(Internet of Things) IoT 物联网(Internet of Things)是目前非常火的。以前,每一个设备都是单纯的 Device,设备和设备之间是没有关系的。但是,物联网的出现打通了这些设备之间的关系。比如:账号和设备都是有绑定关系的,账号和账号之间又有一定的关系,通过这样设备之间也可以建立出一张网络来。 一般来说,图数据库并不是简单的关联关系查询,在图遍历的过程,通常要根据属性做一些计算 。所以一个单单的图关联是完全不能满足要求的。举个例子,这是一个股票新闻实时推荐的场景。 大家知道一般散户炒股并不是高频这样事件驱动的,但是他们也会边看新闻边盯着 K线。所以在这个时候要给他们推荐一些什么新闻呢。一般常见的办法是爬虫获得新闻,清洗完毕后,NLP 分词,提取出关键词后,然后跟股票代码关联上。一般根据监管,可能还要加上一些编辑审核和推送。但大家知道中国股市好的时候,是线下口口相传的。所以有个思路是通过好友圈来推荐新闻:首先会去找用户的好友,然后这些好友可能浏览过一些文章,那么根据驻留时间等,好友对这个文章可能会有一个评分,这个评分用 WL 来表示。好友和好友之间也有一定的亲密度,用 WC 表示。这个亲密度可以来源于之前的聊天次数、转账次数等。同一个人到一篇文章之间可能会有多条路径。比如说到第二篇文章,可能会有几十条路径。所以说这么多条路径的权值之和代表了我和这篇文章的之间的评分。最终给用户推荐文章的时候,希望是把所有的计算结果做 Top N。从线上的结果来看,转化效率比其他几种都要高。 图数据库面临的挑战 再回到技术底层,图数据库面临的技术挑战。 低延时高吞吐 一个挑战就是极低的 latency 和极高的 throughput。比如说查寻好友的好友这样的两跳场景,我们的 Nebula Graph 能在十毫秒以内返回,同时能做到单机 10 万的 pps。 大数据量 另外一个挑战就是数据量。一个典型的银行金融图谱,数据量已经可以达到百 T 规模,大概是几十亿个点和千亿条边的规模。当然,如果图本身只是存点 ID 和点 ID 之间的关联关系,这样的数据量千亿级别其实单机也能存储。但是实际上就像刚才说的,光纯点和边是不够的,还需要有很多图属性做分析,这样单机是肯定不够的。另外就是数据量增长的速度相当快,即使今天单机做个 POC 能存下,可能几个月之后又要扩容了。 复杂的商业逻辑 还有一个挑战就是现在越来越复杂的商业逻辑,用传统的数据库去分析,基本上每一个逻辑都要写 Java 代码来完成查询数据。我们希望不要那么依赖于开发人员,分析人员可以像写 SQL 一样,自己可以搞定。 高可用 最后一个挑战就是关于高可用要求。图数据库刚开始出现的时候,基本上就是一个二级索引。相当于只缓存了点和边之间的关系,真正的属性可能是在别的地方(比如 HBase 或者 MySQL 里面)。Data 本身的正确性和高可用都是都是依赖于这些组件的。但随着使用场景越来越多,这样分离的存储方式性能跟不上,自然就希望数据直接放在图数据库里面。那么各种传统数据库和分布式系统要面临的技术问题也要解决。比如数据多副本的强一致性问题,ACID。对于图数据库的要求越来越多,客户更希望作为一个数据库,而不是作为一个索引或者关系 cache。 Nebula Graph 的特点 存储计算分离 对于 Nebula Graph 来讲,有这么几个技术特点:第一个就是采用了存储计算分离的架构。这样架构主要的考虑其实前面几个 Talk大家都已经讨论了很多,主要好处就是为了上云或者说 弹性 , 方便单独扩容 。上午的 Talk:HBase on Cloud 也有提到,业务水位总是很难预测的,一段时间存储不够了,有些时候计算不够了。在云上或者使用容器技术,计算存储分离的架构运维起来会比较方便,成本也更好控制。大家使用 HBase 那么久,这方面的感触肯定很多。 查询语言 nGQL Nebula Graph 的第二个技术特点是它的查询语言,我们称为 nGQL,比较接近 SQL。唯一大一点的语法差异就是 不用嵌套 (embedding)。大家都知道嵌套的 SQL,读起来是非常痛苦的,要从里向外读。 支持多种后端存储 第三个特点就是 Nebula Graph 支持多种后端存储,除了原生的引擎外,也支持 HBase。因为很多用户,对 HBase 已经相当熟悉了,并不希望多一套存储架构。从架构上来说,Nebula Graph 是完全对等的分布式系统。 计算下推 和 HBase 的 CoProcessor 一样,Nebula Graph 支持数据计算下推。数据过滤,包括一些简单的聚合运算,能够在存储层就做掉,这样对于性能来讲能提升会非常大。 多租户 多租户,Nebula Graph是通过多 Space 来实现的。Space 是物理隔离。 索引 除了图查询外,还有很常见的一种场景是全局的属性查询。这个和 MySQL 一样,要提升性能的主要办法是为 属性建立索引 ,这个也是 Nebula Graph 原生支持的功能。 图算法 最后的技术特点就是关于图算法方面。这里的算法和全图计算不太一样,更多是一个子图的计算,比如最短路径。大家知道数据库通常有 OLTP 和 OLAP 两种差异很大的场景,当然现在有很多 HTAP 方面的努力。那对于图数据库来说也是类似,我们在设计 Nebula Graph 的时候,做了一些权衡。我们认为全图的计算,比如 Page Rank,LPA,它的技术挑战和 OLTP 的挑战和对应的设计相差很大。我们希望 Nebula Graph 能够在 OLTP 这块提供最好的表现。 Nebula Graph 的架构图 下面为大家介绍 Nebula Graph 的架构图:下图(图1)是基于原生存储的,图3 是基于 HBase 的,有一些不同。 基于原生存储的架构图 这条虚线上面是计算层,下面是存储层。 图 1:基于原生存储的架构图 我们先看下计算层,计算层可以理解为把一个 query 翻译成真正需要的执行计划,产生执行计划之后,到下面存储层拿需要的数据。这和传统数据库非常类似,查询语言也很类似。这里面比较重要的事情是查询优化,除了前面提到的计算下推到存储层外,目前一个主要的实现是并发执行。 查询服务架构图 图 2:Query Service 举个例子,查好友的大于 18 岁的好友,可能好友有很多,没有必要等一度好友都返回后,再去查二度好友。当然应该异步来做,一度好友部分返回后,就立刻开始二度查询。有点类似图计算里面的 BSP 和 ASP。这个优化对提升性能有非常大作用。对于 Storage 层来说,又分为上面的 Storage Engine 和 KV Store。因为 Nebula Graph 是分布式系统,数据是分片的。目前的分片方法是静态哈希,和 HBase 不一样。主要是因为图查询基本都是特定 Prefix 的 Scan,Get 很少。比如一个人的好友这样,就是同一个 prefix 的 scan。每一个数据分片会通过 RAFT 协议来保证数据的强一致。这和 HBase 写到底层 HDFS 也不一样。3 台机器上的 Partition1 组成一个 Raft Group。Storage Engine 做的事情比较简单,就是把图语义的查询请求翻译成 KV 的查询请求。关于图右边的 Meta Service,它的主要作用是 schema 管理和集群管理。Nebula Graph 中的点和边都是有属性和版本的,那每个属性的类型和版本在 MetaService 中统一管理。集群管理主要用于运维和鉴权目的,负责机器上下线和对用户做 ACL。 Nebula Graph 基于 HBase 的架构图 图 3:基于 HBase 的架构图 Nebula Graph 的 HBase 版本略微有些不一样,可以看到虚线往下挪了,Storage Service 嵌入到 Query Engine 里面,这是因为 HBase 是独立的服务,Storage Service 进程可以和 Query Engine 放同一台机器上,直接一对一服务了。另外,因为 HBase 自己有 partition,就没必要再分一次了。 Nebula Graph 的数据模型和 Schema 下面介绍下 Nebula Graph 的数据模型和 Schema(每种标签有一组相对应的属性,我们称之为 schema)。前面说到 Nebula Graph 是有向属性图,点和边都有各自属性。点有点属性,Nebula Graph 里面称为 Tag(类型),点可以有多种类型,或者叫多种 Tag。比如一个点既可以是 Tag Person,有属性姓名、年龄;也是 Tag developer,属性是擅长的语言。Tag 是可以像类一样继承的,一个 Tag 继承自另外一个 Tag。边和点略微有点不一样,一条边只能有一种类型。但是两个点之间可以有多种类型的边。另外,像 TTL 这种功能,Nebula Graph 也是支持的。 Nebula Graph 的数据模型和 Schema 这里需要提一下,对于 HBase 和 Nebula Graph 原生存储来说,Schema Version 处理上是不一样的。HBase 是没有 Schema 的。 强 Schema 最大的好处,是知道这条数据什么时候结束的,一行有多少属性是知道的。所以在根据某个版本号取数据的时候,从某一行跳到下一行,不需要对每个属性都扫描一遍。但如果像 HBase 这样弱 Schema 系统,性能消耗是非常大。但相应的,问题就来了,如果要支持强 Schema,要变更 Schema 怎么办?更改 Schema 在 MySQL 里面,往往要锁表的。对于 Nebula Graph 来说,当更改 Schema 时,并不是在原来的数据上进行更改,而是先插入一个新的 Schema,当然这要求写入数据的时候就要记录版本号。这样的话在读的时候,才能知道要用版本。 再解释一下关于 Key 的设计,点和边的 Key 设计是像上面两行这样,一个点是一个 Key,一条边是两个 Key,这样的目的是把起点和出边存在一起,对端的终点和入边存储在一起。这样在查询的时候,可以减少一次网络。另外,对于 Nebula Graph 原生存储和 HBase 存储,属性采用的存储方式也是不一样的。在 HBase 里面,一个属性放在一个 Column 里面。在原生存储里面,所有属性放在一个 Column 里面。这样设计的主要原因是,如果用户使用 HBase 作为底层存储,其实他更期望 HBase 这张表在别的系统里面也可以用,所以说我们考虑把它打散开了。 Nebula Graph 查询语言 nGQL 最后讲一下我们的 Query Language:nGQL 我们说它比较类似 SQL,比如说看这个例子,从某一个点开始向外拓展,用 nGQL 来写就是,GO FROM $id,起始点,然后 OVER edge,沿着某条边,还可以设置一些过滤条件,比如说,从这个点出发,沿着我的好友边,然后去拿,里面年龄大于十八岁的。 那要返回哪些属性?可以用 YIELD,比如说年龄,家庭住址。前面提到,不希望嵌套,嵌套太难读了,所以作为替代, Nebula Graph 用 PIPE 管道。前一条子查询的结果,PIPE 给第二条,然后第二条可以 PIPE 给第三条。这样从前往后读起来,和我们人的思考顺序是一样的。但是管道只解决了一个输入源的问题。 多个输入源的时候怎么办?Nebula Graph 还支持定义某个变量,这个和存储过程有点像。像上面这样,把 $var 定义成一个子查询的结果,再把这个结果拿去给其他子查询使用。还有种很常见的查询是全局匹配,这个和 SQL 里面的 SELECT … FROM … WHERE 一样,它要找到所有满足条件的点或者边。我们这里暂时取名叫做 FIND。大家要是觉得其他名字好也可以在 GitHub 上给我们提 issue。 最后就是一些 UDF,用户自己写的函数,有些复杂的逻辑用 SQL 可能不好描述,Nebula Graph 也希望支持让用户自己写一些代码。因为我们代码是 C++ 写的,再考虑到用户群体,做数据分析用 Python 比较多,我们考虑先支持 C++ 和 Python。 Q&A 现场参会者提问:你们这个架构是 TinkerPop 的实现嘛?区别在哪里? 陈恒的回复如下: 不是的。我们是完全自研的。 首先我们查询语法并不是 Gremlin 那样命令式的,而是更接近 SQL 这种描述式的。可以说下我们的思考,我们主要考虑了查询优化的问题。 你知道像 Gremlin 那样的命令式语言,query 是 .in() .out() 这样一步步组成的,所以查询引擎只能按照给定的命令一步步把数据捞上来,每次序列化速度都很慢的,像 Titan 那样。我们的测试结果应该有几十倍的性能差距。 另外既然用户每步指令是明确的,查询引擎要做优化很难,要非常智能推测出用户整一串指令的最终期望才能优化,这样难度比较高。这个有点像编译器的优化,优化错就很麻烦了。 我们希望像 SQL 这样描述式的,用户说明最终目的就行,怎么处理交给执行引擎来优化,这样做优化比较容易完善,可借鉴的算法也比较多。 当然也和我们以 C++ 做开发语言有关。我们也有想过做 Gremlin 和 nGQL 之间的 driver,主要看社区,欢迎给我们提 issue 上面就是本次 Nebula Graph 参会 HBaseCon Asia2019 的全部内容,最后和大家再说下 Nebula Graph 是完全开源的项目,对于图数据库比较感兴趣的同学可以加 wechat 讨论群,或者在 GitHub 上提 Issue,也欢迎大家给我们支持 star 项目。 Nebula Graph:一个开源的分布式图数据库。 GitHub: https://github.com/vesoft-inc/nebula 官方博客: https://nebula-graph.io/cn/posts/ 微博: https://weibo.com/nebulagraph 数据库 2019-07-24 17:56:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 1. 10g之前 用户的连接将产生会话,当前会话记录保存在v$session中;处于等待状态的会话会被复制一份放在v$session_wait中。当该连接断开后,其原来的连接信息在v$session和v$session_wait中就会被删除。这是10g之前的状况。 2. v$session_wait_history与ASH 若是一个普通的会话(我是指没有大量地耗费资源),则对于性能调整来说无足轻重。但若该会话在活动时大量占用了资源(比如:CPU,内存,I/O等),该会话信息的丢失,将无法评测当时的系统瓶颈究竟是什么。令DBA高兴的是,oracle10g中保留下了v$session_wait中的这些信息。 在10g中新出现了一个视图:v$session_wait_history。这个视图保存了每个活动session在v$session_wait中最近10次的等待事件。但这对于一段时期内的数据库性能状况的监测是远远不够的,为了解决这个问题,在10g中还新添加了一个视图:v$active_session_history。这就是ASH(active session history)。 典型的情况下,为了诊断当前数据库的状态,需要最近的五到十分钟的详细信息。然而,由于记录session的活动信息是很费时间和空间的,ASH采用的策略是:保存处于等待状态的活动session的信息,每秒从v$session_wait中采样一次,并将采样信息保存在内存中。 3. AWR 注意,ASH的采样数据是保存在内存中。而分配给ASH的内存空间是有限的,当所分配空间占满后,旧的记录就会被覆盖掉;而且数据库重启后,所有的这些ASH信息都会消失。这样,对于长期检测oracle的性能是不可能的。在Oracle10g中,提供了永久保留ASH信息的方法,这就是AWR(auto workload repository)。 由于全部保存ASH中的信息是非常耗费时间和空间的,AWR采用的策略是:每小时对v$active_session_history进行采样一次,并将信息保存到磁盘中,并且保留7天,7天后旧的记录才会被覆盖。这些采样信息被保存在视图wrh$_active_session_history中。而这个采样频率(1小时)和保留时间(7天)是可以根据实际情况进行调整的,这就给DBA们提供了更加有效的系统监测工具。 AWR永久地保存系统的性能诊断信息,由SYS用户拥有。一段时间后,你可能想清除掉这些信息;有时候为了性能诊断,你可能需要自己定义采样频率来获取系统快照信息。Oracle 10g在包dbms_workload_repository中提供了很多过程,通过这些过程,你可以管理快照并设定基线(baselines)。 4. 小结 这样,我们就知道了ASH和AWR产生的原因和功能。ASH保存了系统最新的处于等待的会话记录,可以用来诊断数据库的当前状态;而AWR中的信息最长可能有1小时的延迟,所以其采样信息并不能用于诊断数据库的当前状态,但可以用来作为一段时期内数据库性能调整的参考。 对于这些视图间的继承关系,eygle给出了一个关系图: 图1 各个视图的层次 其中视图dba_hist_active_sess_history是wrh$_active_session_history和其他几个视图的联合展现,通常通过这个视图进行历史数据的访问。 分享: 0 喜欢 数据库 2019-07-22 17:28:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> select * from ti_road_node_code a where a.road_node_id not in ( select en_road_node_id from ti_road_node_relation b) 15毫秒 select * from ti_road_node_code a left join ti_road_node_relation b where a.road_node_id =en_road_node_id and isnull(b.ex_road_node_id) - 报错 select a.* from ti_road_node_code a left join ti_road_node_relation b on a.road_node_id =b.en_road_node_id where isnull(b.ex_road_node_id) 282毫秒 select a.* from ti_road_node_code a left join ti_road_node_relation b on a.road_node_id =b.en_road_node_id where isnull(b.en_road_node_id) 一样 SELECT a.* FROM ti_road_node_code a WHERE NOT EXISTS (SELECT 1 FROM ti_road_node_relation b WHERE b.en_road_node_id = a.road_node_id) 540毫秒 https://blog.csdn.net/a3060858469/article/details/79651428 数据库 2019-07-19 10:57:00 【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>> 上周五(7月12日)巨杉数据库参与了由得到App主办八里庄技术沙龙活动,分享主题是关于分布式数据库架构与实战。 以下就是根据巨杉数据库现场分享的内容进行的分享实录整理。 巨杉数据库简介 巨杉,专注新一代分布式数据库技术研发,自2011年成立以来,坚持从零开始打造分布式开源数据库引擎,是中国首家连续两年入选 Gartner 数据库报告的数据库厂商。 巨杉数据库的主要产品包括 SequoiaDB 分布式关系型数据库与 SequoiaCM 企业内容管理软件,应用场景包括分布式在线交易、数据中台、分布式内容管理等。 目前,巨杉数据库已在近百家大型商业银行核心生产业务上线,并广泛应用于金融、电信、政府、互联网、交通等领域,企业用户总数超过1000家。 数据库应如何应对微服务发展趋势 很多企 业 内部的 应 用开 发 都在从 传统 中 间 件加数据 库 的 “ 烟囱式 ” 开 发 ,向微服 务 架构 转 型。而在微服 务 体系架构中,几乎每个微服 务 都需要提供数据持久化的能力,而用 户 也希望每个微服 务 所承 载 的数据量能 够 无限的 弹 性 扩张 。但是,在采用微服 务 架构的 过 程中,每个微服 务 使用自身独立的数据 库 存 储 又会使 过 去集中在一个地方的数据分散到很多不同的 设备 中,造成整个 IT 架构的数据 严 重碎片化。 实际上,当企业用户采用微服务体系架构的时候,从数据管理的角度,业界有两种做法。 第一种:就是 对应 用程序 进 行微服 务 改造,底 层 数据 库 使用 传统 集中式数据 库进 行存 储 。 这 种做法学 习 成本也 较 低,其存在数据 紧 耦合,无法 弹 性 扩张 ,以及可能存在 单 点故障等 问题 。 第二种:每一 组 微服 务对应 一个独立的小数据 库 ,往往使用 MySQL 或 PostgreSQL , 业 界使用 较 多的。 这 种机制能 够 解决集中式存 储 的 问题 ,但是也 带 来了新的挑 战 ,包括数据极度碎片化,在微服 务 之 间 无法共享,运 维 成本极其高昂。 两种 办 法都不能很好的解决微服 务 下数据存 储 管理的 问题 ,因此分布式数据 库 就是要解决上述的两个 问题 。第一就是 针对 每个微服 务 做到数据 弹 性 扩张 ,第二就是 对 整个企 业 IT 做到数据的 统 一治理从而避免碎片化存 储 。 联机交易需要什么样的分布式数据库 联机交易数据库特 性 适合微服 务 的分布式数据 库 都 应该 具有特性,主要 应该 从两大 维 度。一是 对传统 技 术 的兼容,二是技 术 和架构的 创 新。 传统技术的兼容方面,必须支持 ACID 和 SQL 的完整性。 从新技 术 的前瞻性来看,首先,分布式数据 库 的核心价 值 在于数据 库资 源池在保 证 与 传统 数据 库 100% 兼容的基 础 上,必 须满 足分布式 弹 性 扩张 ,当 资 源池里面空 间 和 计 算能力不足 时 ,需要通 过动态 增加 计 算存 储节 点的方式 进 行 扩 容。 其次,大家采用的开 发 流程、 SQL 标准、以及安全策略各不相同,因此分布式数据库必须能够支持多种模式的访问接口 。 最后, HTAP ,即交易分析混合 处 理能力。 联 机交易数据与 实时 数据分析在 资 源池内 进 行 资 源隔离, 对 同一份数据 库访问 并可以做到互不干 扰 。适合微服 务 的数据 库 必 须 有 较强 的交易分析混合 处 理能力。 分布式数据库架构及关键特性 巨杉数据 库实例化 架构 要打造适合微服 务 架构的数据 库 ,巨杉数据 库 采用了 计 算存 储 分离的架构。其中存 储层 采用自研的原生分布式数据 库 引擎,上 层计 算 层则 可以 创 建成百上千个数据 库实 例,同 时 每个数据 库实 例 对应 用完全透明,不需感知。如 图 5 所示。 计算与存储分离架 构 对于计算和存储分离,把分布式存储层展开, SeuqoiaDB 分布式存 储 引擎有很多 节 点角色,其中有 协调节 点 编 目 节 点和数据 节 点和 编 目 节 点。 协调节 点是数据路由,数据存 储 在数据 节 点。 编 目 节 点保存整个数据集群系 统 信息。数据 节 点把数据打散到不同的分区中,使用三副本架构,任何一个 节 点出故障,不影响正常运行。 巨杉数据 库 核心 应 用 场 景 巨杉数据 库 大 维 度下的定位是一款真正的金融 级 分布式关系型数据 库 。 巨杉数据 库 目前在企 业级应 用 场 景主要包括分布式在 线 交易、数据中台以及分布式内容管理。 在 线 交易是数据 库 最广泛 应 用的 场 景之一,通常用来支撑核心 业务 运 营 。分布式在 线 交易数据 库 核心 业务 价 值 包括,分布式架构 转 型,高并 发 、高 处 理能力, 业务 持 续扩 展能力以及自主可控与数据安全要求。 数据中台提供全量数据的 实时 在 线 服 务 ,泛指 传统 核心交易以外的所有 对 外服 务业务 。 内容管理平台 为 企 业 提供存 储 、管理和使用海量非 结 构化数据能力。常 见应 用包括影像平台、文档管理平台、音 视频 双 录 系 统 等。 分布式事 务 能力 巨杉数据 库 支持分布式事 务 ,使用二段提交确保多个 节 点之 间 数据一致, 锁 机制是悲 观锁 ,支持 MVCC 的 读 写提交能力。 HTAP 读写分 离 多租户物理隔离能力 通过数据库引擎的分布式架构、Multimodel多模数据存储类型以及实例化的数据库实例管理,巨杉数据库可以实现多租户啊管理的能力、HTAP等等云化数据库必须的技术能力。 最后八里庄技 术 委 员 会主席李丹与巨杉数据 库 技 术专 家合照留念,期待更多数据 库 技 术 交流。 数据库 2019-07-18 18:35:00 |
---|