首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

使用StreamingPro 快速构建Spark SQL on CarbonData

前言 CarbonData已经发布了1.0版本,变更还是很快的,这个版本已经移除了kettle了,使得部署和使用 变得很简单,而且支持1.6+ ,2.0+等多个Spark版本。 StreamingPro可以使得你很简单通过一个命令就能体验Carbondata,并且支持Http/JDBC的访问形态。 下载Spark发行版 比如我下载后的版本是这个: spark-1.6.3-bin-hadoop2.6。 下载StreamingPro 地址在这: https://pan.baidu.com/s/1eRO5Wga ,你会得到一个比较大的Jar包。 同时你需要到maven下载一个 carbondata-spark-1.0.0-incubating.jar ,这个因为一些特殊原因才会用到。 你需要一个数据库 因为我们用到了Hive 的mysql,所以你需要准备一个可以连接的数据库。只要能连接就行。如果没有,比如你是mac的话,用 brew install mysql即可。然后brew services start mysql 创建一个数据库: create database hive CHARACTER SET latin1 //如果数据库包字符异常啥的,启动完streamingpro后到数据库做如下更改: alter table PARTITIONS convert to character set latin1; alter table PARTITION_KEYS convert to character set latin1; 写一个hive-site.xml文件 <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://127.0.0.1:3306/hive?createDatabaseIfNoExist=true</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>你的mysql账号</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>你的mysql密码</value> </property> <property> <name>hive.metastore.warehouse.dir</name> <value>file:///tmp/user/hive/warehouse</value> </property> <property> <name>hive.exec.scratchdir</name> <value>file:///tmp/hive/scratchdir</value> </property> <property> <name>hive.metastore.uris</name> <value></value> </property> <property> <name>datanucleus.autoCreateSchema</name> <value>true</value> </property> </configuration> 可以启动了 //streamingpro jar包所处的目录, //里面新建一个query.json文件,里面放一个大括号就行 SHome=/Users/allwefantasy/streamingpro ./bin/spark-submit --class streaming.core.StreamingApp \ --master local[2] \ --name sql-interactive \ --jars /Users/allwefantasy/.m2/repository/org/apache/carbondata/carbondata-spark/1.0.0-incubating/carbondata-spark-1.0.0-incubating.jar \ --files $SHome/hive-site.xml \ --conf "spark.sql.hive.thriftServer.singleSession=true" \ $SHome/streamingpro-0.4.8-SNAPSHOT-online-1.6.1.jar \ -streaming.name sql-interactive \ -streaming.job.file.path file://$SHome/query.json \ -streaming.platform spark \ -streaming.rest true \ -streaming.driver.port 9004 \ -streaming.spark.service true \ -streaming.thrift true \ -streaming.enableCarbonDataSupport true \ -streaming.enableHiveSupport true \ -streaming.carbondata.store /tmp/carbondata/store \ -streaming.carbondata.meta /tmp/carbondata/meta参数比较多。大家不用管他。 这样http端口是9004, jdbc端口是 10000。 我们可以通过http创建一张表 , city string, age Int) STORED BY 'carbondata' curl --request POST \ --url http://127.0.0.1:9004/run/sql \ --header 'cache-control: no-cache' \ --header 'content-type: application/x-www-form-urlencoded' \ --header 'postman-token: 731441ac-c398-9a1b-2f06-8725ddbe84cd' \ --data 'sql=CREATE%20TABLE%20IF%20NOT%20EXISTS%20test_table4(id%20string%2C%20name%20string%2C%20city%20string%2C%20age%20Int)%20STORED%20BY%20'\''carbondata'\'''写入数据前,我们建立一个sample.csv的文件, id,name,city,age 1,david,shenzhen,31 2,eason,shenzhen,27 3,jarry,wuhan,35然后将这个文件导入: //实际SQL:LOAD DATA LOCAL INPATH '/Users/allwefantasy/streamingpro/sample.csv' INTO TABLE test_table4 curl --request POST \ --url http://127.0.0.1:9004/run/sql \ --header 'cache-control: no-cache' \ --header 'content-type: application/x-www-form-urlencoded' \ --header 'postman-token: 5eb19ab4-653c-d05f-29ab-6003d7e83755' \ --data 'sql=LOAD%20DATA%20LOCAL%20INPATH%20%20'\''%2FUsers%2Fallwefantasy%2Fstreamingpro%2Fsample.csv'\''%20%20INTO%20TABLE%20test_table4'这个使用我们可以用http查询: //sql: SELECT * FROM test_table4 curl --request POST \ --url http://127.0.0.1:9004/run/sql \ --header 'cache-control: no-cache' \ --header 'content-type: application/x-www-form-urlencoded' \ --header 'postman-token: d99349ae-b226-8a4e-4d65-d92b1771c111' \ --data 'sql=SELECT%20*%20FROM%20test_table4'你也可以写一个jdbc程序: object ScalaJdbcConnectSelect { def main(args: Array[String]) { // connect to the database named "mysql" on the localhost val driver = "com.mysql.jdbc.Driver" val url = "jdbc:hive2://localhost:10000/default" // there's probably a better way to do this var connection:Connection = null try { // make the connection Class.forName(driver) connection = DriverManager.getConnection(url) // create the statement, and run the select query val statement = connection.createStatement() val resultSet = statement.executeQuery("SELECT * FROM test_table4 ") while ( resultSet.next() ) { println(" city = "+ resultSet.getString("city") ) } } catch { case e => e.printStackTrace } connection.close() } }完成。

优秀的个人博客,低调大师

EDAS:快速搞定分布式应用

本期分享嘉宾: 滨雨 多年IT领域工作经验,先后在华为、阿里基础架构部担任软件工程师、项目经理。目前从事存储、cdn、视频、中间件等技术领域的支持,喜欢新技术,喜欢新挑战,喜欢钻研。 攻城狮:谁又动了我模块接口?谁又改了我模块逻辑??? 运维:有bug!模块之间的调用跟个蜘蛛网一样,我怎么排查! 测试:这么复杂的调用逻辑,我的自动化测试用例咋写?! 架构师:业务上升了,系统要部署到多台服务器才行,这我怎么拆?! 新人入职后:代码太难理解,想shi的心都有了……. 老板:为啥大半年过去了需求还没搞定!!! 作为一个开发者,你是否经历过这样的咆哮? 这样的场景出现,不是谁的脾气有bug,而是打开方式或许不对。今天我们就通过一个真实案例,来看看分布式开发对消灭吐槽,促进团队和谐的作用。 单体应用很丰满,现实很骨感 X公司是一个秉承传统的开发方式的典型,如下图的

优秀的个人博客,低调大师

【Spark Summit East 2017】工程快速索引

更多精彩内容参见云栖社区大数据频道https://yq.aliyun.com/big-data;此外,通过Maxcompute及其配套产品,低廉的大数据分析仅需几步,详情访问https://www.aliyun.com/product/odps。 本讲义出自Daniel Lemire在Spark Summit East 2017上的演讲,主要介绍了当代计算机硬件提供了大量新的性能的机会。然而高性能编程仍是一项艰巨的挑战,演讲中给出了一些对于设计侧重于压缩位图索引的更快索引的经验教训。压缩位图索引加速查询在流行系统,如Spark, Git, Elastic, Druid与Apache Kylin中的应用。

优秀的个人博客,低调大师

利用云存储快速实现网站备份

背景 真正运营过网站的人都知道,数据对一个网站来说至关重要,因此,网站数据备份也是日常必做工作。因为误操作,网站被攻击等种种原因都会导致数据丢失,这时,你才会明白“有备无患”的道理。而且由于站点文件的备份过大,用邮件无法发送。 阿里云OSS云储存支持任意文件类型类型存储;同时按量付费的,占用多大的存储空间,付费多少;此外,内网流入流量完全免费。因此OSS适用于图片、音频、视频、日志等海量文件的存储,支持各种终端设备,Web网站程序和移动应用直接向 OSS 写入或读取数据。 方案 通过多备份工具和阿里云OSS平台将网站直接备份到阿里云上。 所需工具包括:多备份、阿里云OSS平台。 具体操作步骤 第一步:登录多备份官网,进入之后,先别急着创建备份任务。先点击邮箱(图中红条处),进入你的个人中心。 你可以看到,这里会显示“已绑定”的网盘和“未绑定”的网盘。 第二步:在“未绑定”的网盘列表中,找到“阿里云”,点击后会弹出下面的页面,提示你填写AccesskeyID等信息。这里有一点需要注意的是:你需要设置你的Bucket属性的读写权限为“公共读”及防盗链规则Refer:http://www.dbfen.com,http://www.dbfen.com。 第三步:登录阿里云官网,找到“对象存储OSS”。开通 OSS 服务。在使用阿里云 OSS 服务之前,确保您已经注册了阿里云账号并完成实名认证。如果您还没有创建阿里云账号,系统会在您开通 OSS 时提示您注册账号。点击OSS产品详情页中的立即开通; 第四步:开通服务后,点击管理控制台直接进入 OSS 管理控制台界面。 您也可以点击位于首页右上方菜单栏的管理控制台,进入阿里云管理控制台首页,然后点击下图所示按钮进入 OSS 管理控制台界面。 第五步:进入控制台之后,别忘了我们的目的是要找到AcesskeyID等信息。所以,OSS 管理控制台界面。单击Bucket 管理>新建 Bucket,新建 Bucket对话框将弹出。 第六步:在BucketName框中,输入存储空间名称。存储空间的命名必须符合命名规范。所选定的存储空间名称在阿里云 OSS 的所有现有存储空间名称中必须具有唯一性。创建后不支持更改存储空间名称。有关存储空间命名的更多信息,请参阅OSS 基本概念介绍。 在在 所属地域 框中,下拉选择该存储空间的数据中心。订购后不支持更换地域。如需要通过 ECS 内网访问 OSS,可选择与你 ECS 相同的地域。有关地域的更多信息,请参阅阿里云OSS 开发人员指南中的对应章节。读写权限框中,下拉选择对应的权限。 公共读写:任何人(包括匿名访问)都可以对该存储空间中的文件进行读写操作,所有这些操作产生的费用由该存储空间的创建者承担,请慎用该权限; 公共读:只有该存储空间的创建者可以对该存储空间内的文件进行写操作,任何人(包括匿名访问)可以对该存储空间中的文件进行读操作; 私有:只有该存储空间的创建者可以对该存储空间内的文件进行读写操作,其他人无法访问该存储空间内的文件。 这里我们选择的是“公共读”,单击 “ 提交”。存储空间创建完成。 第七步:我们看到导航栏,右上角有我们需要的Access key管理按钮,点击进去。 第八步:将bucket,AcesskeyID等信息复制,填入多备份网站上提示的绑定阿里云的页面中。 就这样,我们就完成了阿里云网盘的绑定啦,很简单吧!另外,阿里云OSS是按量付费的,你占了多大的存储空间,就付多少钱。 第九步:阿里云绑定之后,大家可以回到多备份的控制面板,去创建属于自己的备份任务啦,但是记住在存储位置那里要选择“阿里云”哟! 相关资料: 关于本教程详细更多细节:http://jingyan.baidu.com/article/4dc40848943ea8c8d946f1af.html 阿里云对象存储OSS使用方法:http://www.chinaz.com/web/2015/0909/444441_2.shtml 多备份相关资料:http://lusongsong.com/reed/1143.html

优秀的个人博客,低调大师

MySQL 不完全入门指南

由于 MySQL 的整个体系太过于庞大,文章的篇幅有限,不能够完全的覆盖所有的方面。所以我会尽可能的从更加贴进我们日常使用的方式来进行解释。 小白眼中的 MySQL 首先,对于我们来说,MySQL 是个啥?我们从一个最简单的例子来回顾一下。 这可能就是最开始大家认知中的 MySQL。那 MySQL 中是怎么处理这个查询语句的呢?换句话说,它是如何感知到这串字符串是一个查询语句的?它是如何感知到该去哪张表中取数据?它是如何感知到该如何取数据? 到目前为止,都不知道。接下来我们一步一补来进行解析。 连接池 首先,要去 MySQL 执行命令,肯定是需要连接上 MySQL 服务器的,就像我们通过「用户名」和「密码」登陆网站一样。所以,我们首先要认识的就是连接池。 这种池化技术的作用很明显,复用连接,避免频繁的销毁、创建线程所带来的开销。除此之外,在这一层还可以根据你的账号密码对用户的合法性、用户的权限进行校验。 每一个连接都对应一个线程,「服务器」 和 「MySQL」 都一样,服务器的一个线程从服务器的连接池中取出一个连接,发起查询语句。MySQL 服务器的线程从连接池中取出一个线程,继续后续的流程。 那么后面的流程是啥呢?当然是分析 SQL 语句了。 分析器 很明显,MySQL 肯定得知道这个 SQL 是不是个合法的 SQL 语句,以及 SQL 语句到底要干啥? 就好像有个哥们疯狂的敲你家门,门打开了,下一步是干嘛?肯定得问他是谁?来干嘛? 所以,下一步就是要将 SQL 进行解析。解析完成之后,我们就知道当前的 SQL 是否符合语法,它到底要干嘛,是要查询数据?还是要更新数据?还是要删除数据? 很简单,我们肉眼能能明显看出来一条 SQL 语句是要干嘛。但电脑不是人脑,我们得让电脑也能看懂这条 SQL 语句,才能帮我们去做后面的事。 知道了这个 SQL 语言要干嘛之后,是不是就可以开始执行操作了呢? 并不是 优化器 MySQL 除了要知道这条 SQL 要干嘛,在执行之前,还得决定怎么干,怎么干是最优解。 还是刚刚那个例子,隔壁的哥们敲开了你家的门,说哥们儿,我家里这停水了,想找你施(白)舍(漂) 24 瓶矿泉水。我们暂且不去讨论,他为什么需要 24 瓶矿泉水。 我们要讨论的是,我们要怎么把这 24 瓶矿泉水拿给他。因为你刚刚想起来,矿泉水在之前被你一顿操作全扔柜子了。 你是要每次拿个 4 瓶,跑 6 趟呢?还是找个箱子,把 24 瓶装满再搬出去给他。 这差不多就是优化器要做的事情,优化器会分析你的 SQL,找出最优解。 再举个正经的例子,假设 SELECT nameFROMstudentwhereid= 1 语句执行时,数据库里有 1W 条数据,此时有两种方案: 查出所有列的 name 值,然后再遍历对比,找到 id=1 的 name 值 直接找到 id=1 的数据,然后再取 name 的值 用屁股想想都知道应该选方案2. 找到了怎么做之后,接下来就需要落实到行动上了。所以,接下来执行器闪亮登场。 执行器 执行器会掉用底层存储引擎的接口,来真正的执行 SQL 语句,在这里的例子就是查询操作。 至此,MySQL 这个黑盒子已经被我们一步一步的揭开了面纱。但是在揭开最后一片面纱的时候,我们又发现了新的黑盒子。那就是存储引擎。 我们到目前为止,就只知道它的名字,至于其如何存储数据,如何查询数据,一概不知。 存储引擎 MySQL 的存储引擎有很多的种类,分别适用于不同的场景。大家可以这么理解,存储引擎就是一个执行数据操作的接口(Interface),而底层的具体实现有很多类。 InnoDB、MyISAM、Memory、CSV、Archive、Blackhole、Merge、Federated、Example 用的最广泛的,就是 InnoDB 了。打从 MySQL 5.5 之后,InnoDB 就是 MySQL 默认的存储引擎了。 所以,存储引擎其实并不是什么高大上的东西,跟什么大学拿去交作业的图书馆管理系统区别,就差了亿点而已。 或者,我再举个例子。我们往我们电脑上的文件中写入数据,此时由于 OS 的优化,数据并不会直接写入磁盘,因为 I/O 操作相当的昂贵。数据会先进入到 OS 的 Cache 中,由 OS 之后刷入磁盘。而 MySQL 在整个的逻辑结构上,跟计算机写文件差不多。 从上面的例子看出,存储引擎可以分为两部分: 内存 磁盘 所以,从宏观上来说,MySQL 就是把数据在缓存在内存中,鼓捣鼓捣,然后在某些时候刷入磁盘中去,就这么回事。 接下来,就让我们深入存储引擎 InnoDB 的底层原理中相当重要的一部分——内存架构。 简单来说,InnoDB 的内存由以下两部分组成: Buffer Pool Log Buffer 从上面画的图就能够看出,Buffer Pool 是 InnoDB 中非常重要的一部分,MySQL 之所以这么快其中一个重要的原因就是其数据都存在内存中,而这个内存就是 Buffer Pool。 Buffer Pool 一般来说,宿主机的 80% 的内存都会分配给 Buffer Pool。这个很好理解,内存越大,就能够存下更多的数据。这样一来更多的数据将可以直接在内存中读取,可以大大的提升操作效率。 那 Buffer Pool 中到底是如何存储数据的呢?如果其底层的数据存储不进行特殊的设计、优化,那么 InnoDB 在取数据的时候除了整个遍历之外,没有其他的捷径。而如果那样做,MySQL 也不会获得今天这样的地位。 页 如果我们能想象一下,InnoDB 会如何组织内存的数据。想象一下,图书馆的书是直接一本一本的摊在地上好找,还是按照类目、名称进行分类、放到对应的书架上、再进行编号好找?结论自然不言而喻。Buffer Pool 也采用了同样的数据整合措施。 InnoDB 将 Buffer Pool 分成了一张一张的页(Pages),同时还有个 Change Buffer(后面会详细讲,这里先知道就行)。分成一页一页的数据就能够提升查询效率吗?那这个页里面到底是个啥呢? 可以从上图看到,页和页之间,实际上是有关联的,他们通过双向链表进行连接,可以方便的从某一页跳到下一页。 那数据在页中具体是如何存储的呢? User Records 当然,光跳来跳去的并不能说明任何问题,我们还是揭开页(Pages)这个黑盒的面纱吧。 ! 可以看到,主要就分为 上一页指针 下一页指针 User Records 其余字段 为了方便理解,其余字段我后续会补充 上一页指针、下一页指针就不多赘述,就是一个指针。重点我们需要了解 User Records。 User Records 就是一行一行的数据**(Rows)最终存储的地方,其中,行与行之间形成了单向链表**。 看了这个单向链表不知道你有没有一个疑问。 我们知道,在聚簇索引中,Key 实际上会按照 Primary Key 的顺序来进行排列。那在 User Records 中也会这样吗?我们插入一条新的数据到 User Records 中时,是否也会按照 Primary Key 的顺序来对已有的数据重排序? 如果每次插入数据都需要对 User Records 中的数据进行重排序,那么 MySQL 的江湖地位将再次不保。 虽然在图中看起来是按照「主键」的顺序存储的,但实际上是按照数据的插入顺序来存储的,先到的数据会在前面,后到的数据会在后面,只是每个 User Records 数据的指针指向的不是物理上的下一个,而是逻辑上的下一个。 用图来表示,大概如下: 可以理解为数组和链表的区别。 看到这,那么问题来了,说好的不遍历呢?这不是打脸吗?因为从上图可以看出,我要找查找某个数据是否存在于当前的页(Pages)中,只能从头开始遍历这个单向链表。 就这?还敢号称高性能?当然,InnoDB 肯定不是这么搞的。这下就需要从「其余字段」中取出一部分字段了来解释了。 Infimum 和 Supremum 分别代表当前页(Pages)中的最大和最小的记录。 可以看到,有了 Infimum 和 Supremum,我们不需要再去遍历 User Records 就能够知道,要找的数据是否在当前的页中,大大的提升了效率。 但其实还是有问题,比如我需要查询的数据不在当前页中还好,那如果在呢?那是不是还是逃不了 O(N) 的链表遍历呢?算不算治标不治本? 这个时候,我们又需要从「其余字段」中抽一个概念出来了。 Page Directory 顾名思义,这玩意儿是个「目录」,可以看下图。 ! 可以看到,每隔一段记录就会在 Page Directory 中有个记录,这个记录是一个指向 User Records 中记录的一个指针。 不知道这个设计有没有让你想起跳表(Skip List)。那这个 Page Directory 中的目录拿来干嘛呢? 有了 Page Directory,就可以对一页中的数据进行类似于跳表的中的查询。在 Page Directory 中找到对应的「位置」之后,再根据指针跳到对应的 User Records 上的单链表,进行查询。如此一来就避免了遍历全部的数据。 上面提到的「位置」,其实有个专业的名词叫「槽位(Slots)」。每一个槽位的数据都是一个指向了 User Records 某条记录的指针。 当我们新增每条数据的时候,就会同步的对 Page Directory 中的槽位进行维护。InnoDB 规定每隔 6 条记录就会创建一个 Slot。 了解到这里之后,关于如何高效地在 MySQL 查询数据就已经了解的差不多了。 想了解「其余字段」还有哪些、以及「页」的完整面貌的,可以去看看我之前写的页的文章 MySQL 页完全指南——浅入深出页的原理,再次就不再赘述。 索引 了解完页之后,索引是什么就一目了然了。InnoDB 底层的存储使用的数据结构为 B+树,B树的变种。MySQL 中有两种索引,分别是聚簇索引和非聚簇索引,听着很高大上。 其实了解完「页」的底层原理,要区分它们就变成的很简单了。 聚簇索引的叶子结点上,存储的是「页」 **非聚簇索引(二级索引)**的叶子结点上,存储的是「主键ID」。很多时候,我们都需要通过非聚簇索引拿到主键,再根据这个主键去「聚簇索引」中拿完整的数据,这个过程还有一个很有意思的名字叫「回表」。 至于为什么底层数据结构要用 B+树 和 B树,大概是因为以下三点: B+树能够减少 I/O 的次数 查询效率更加的稳定 能够更好的支持范围查询 详细的原因可以参考之前写的 浅入浅出 MySQL 索引 更新数据 为什么下一步就是要看如何更新数据呢?因为上述的「页」的原理主要都是基于「查询」的前提在讲,看完了之后对查询的过程应该了然于胸了。接下来我们就来看看更新的时候会发生什么。 首先,如果我们插入了某条 id=100 的数据,然后再去更新的话,这条数据是一定的在 Buffer Pool 的。这句话看似是废话(我都写到数据库了那肯定存在啊) 那我换个说法,更新的时候,id=100 这条数据可能不在 Buffer Pool 中。为什么之前写入了 Buffer Pool,之后再来更新 Buffer Pool 中又没有呢? 答案是内存是有限的,我们不可能无限的向 Buffer Pool 中插入数据。熟悉 Redis 的知道,Redis 在运行时会有「过期策略」,有以下三种: 定时过期 惰性过期 定期过期 而 Buffer Pool 同样也是基于内存,同样也需要一个「过期策略」来清理掉一些不常被访问的数据,来为新的数据、热点数据腾出空间。 当然,这里的清理掉,并不是删除,而是将它们刷入磁盘 更新数据时,如果发现对应的数据不存在,就会将那个数据所在的页加载到 Buffer Pool 中来。注意,这里并不是只加载 id=100 这一行,而是其所在的一整「页」数据。 加载到 Buffer Pool 中之后,再对 Buffer Pool 中的数据进行更新。当然,这个情况对我们开发人员来说,是针对聚簇索引的。 还有另一种情况是针对「 非聚簇索引」 的。 Change Buffer 很简单,当我们更新了某些字段之后,假设这些字段是组成非聚簇索引的字段,就会涉及到非聚簇索引的更新,但不巧的是该非聚簇索引所在的页不在 Buffer Pool 中。按照之前的说法,需要将对应的页(Pages)加载到 Buffer Pool 中来。 但是这里有一个很大的问题,这个二级索引可能之后**根本不会被用到,**那这样一来,刚刚昂贵的 I/O 操作就被浪费掉了。积少成多,如果每次涉及到更新二级索引发现在 Buffer Pool 中不存在,都去做 I/O 操作,那也是一个相当大的开销。 所以,InnoDB 才设计了 Change Buffer。Change Buffer 就是专门用来存储当「非聚簇索引」所在的页不在 Buffer Pool 时的更改的。 换句话说,当对应的非聚簇索引被修改并且对应的页(Pages)不在 Buffer Pool 中时,会将其改动暂存在 Change Buffer,等到其对应的页被其他的请求加载进 Buffer Pool 时,就会将 Change Buffer 中暂存的数据 和 Buffer Pool 中的数据进行合并。 当然,Change Buffer 这个设计也不是没有缺点。当 Change Buffer 中有很多的数据时,全部合并到Buffer Pool可能会花上几个小时的时间,并且在合并的期间,磁盘的 I/O 操作会比较频繁,从而导致部分的CPU资源被占用,对 MySQL 整体的性能是有影响的。 那你可能会问,难道只有被缓存的页加载到了 Buffer Pool 才会触发合并操作吗?那要是它一直没有被加载进来,Change Buffer 不就被撑爆了?很显然,InnoDB 在设计的时候考虑到了这个点。除了对应的页加载,提交事务、服务停机、服务重启都会触发合并。 Adaptive Hash 自适应哈希索引(Adaptive Hash Index)是配合 Buffer Pool 工作的一个功能。自适应哈希索引使得MySQL的性能更加接近于内存服务器。 如果要启用自适应哈希索引,可以通过更改配置innodb_adaptive_hash_index来开启。如果不想启用,也可以在启动的时候,通过命令行参数--skip-innodb-adaptive-hash-index来关闭。 自适应哈希索引是根据索引 Key 的前缀来构建的,InnoDB 有自己的监控索引的机制,当其检测到为当前某个索引页建立哈希索引能够提升效率时,就会创建对应的哈希索引。如果某张表数据量很少,其数据全部都在 Buffer Pool 中,那么此时自适应哈希索引就会变成我们所熟悉的指针这样一个角色。 当然,创建、维护自适应哈希索引是会带来一定的开销的,但是比起其带来的性能上的提升,这点开销可以直接忽略不计。但是,是否要开启自适应哈希索引还是需要看具体的业务情况的,例如当我们的业务特征是有大量的并发 Join 查询,此时访问自适应哈希索引就会产生竞争。 并且如果业务还使用了 LIKE 或者 % 等通配符,根本就不会用到哈希索引,那么此时自适应哈希索引反而变成了系统的负担。 所以,为了尽可能的减少并发情况下带来的竞争,InnoDB 对自适应哈希索引进行了分区,每个索引都被绑定到了一个特定的分区,而每个分区都由单独的锁进行保护。 其实通俗点理解,就是降低了锁的粒度。分区的数量我们可以通过配置innodb_adaptive_hash_index_parts来改变,其可配置的区间范围为[8, 512]。 过期策略 上面提到,Buffer Pool 也会有自己的过期策略,定时的将不需要的数据刷回磁盘,为后续的请求腾出空间。那么,InnoDB 是怎么知道哪些数据是不需要的呢? 答案是 LRU 算法 LRU是**(L**east Recently Used)的简称,表示最近最少使用,Redis 的内存淘汰策略中也有用到 LRU。 但是 InnoDB 所采用的 LRU 算法和传统的 LRU 算法还不太一样,InnoDB 使用的是改良版的 LRU。那为啥要改良?这就需要了解原生 LRU 在 MySQL 有啥问题了。 在实际的业务场景下,很有可能会出现全表扫描的情况,如果数据量较大,那么很有可能会将之前 Buffer Pool 中缓存的热点数据全部换出。这样一来,热点数据被再次访问时,就需要执行 I/O 操作,而这样就会导致该段时间 MySQL 性能断崖式下跌。而这种情况还有个专门的名词,叫——缓冲池污染。 这也是为什么 InnoDB 要对 LRU 算法做优化。 优化之后的链表被分成了两个部分,分别是 New Sublist 和 Old Sublist,其分别占用了 Buffer Pool 的 3/4 和 1/4。 链表的前 3/4,也就是 New Sublist 存放的是访问较为频繁的页。而后 1/4 也就是 Old Sublist 则是反问的不那么频繁的页。Old Sublist中的数据,会在后续 Buffer Pool 剩余空间不足、或者有新的页加入时被移除掉。 了解了链表的整体构造和组成之后,我们就以新页被加入到链表为起点,把整体流程走一遍。首先,一个新页被放入到Buffer Pool之后,会被插入到链表中 New Sublist 和 Old Sublist 相交的位置,该位置叫MidPoint。 该链表存储的数据来源有两部分,分别是: MySQL 的预读线程预先加载的数据 用户的操作,例如 Query 查询 默认情况下,由用户操作影响而进入到 Buffer Pool 中的数据,会被立即放到链表的最前端,也就是 New Sublist 的 Head 部分。但如果是 MySQL 启动时预加载的数据,则会放入MidPoint中,如果这部分数据再次被用户访问过之后,才会放到链表的最前端。 这样一来,虽然这些页数据在链表中了,但是由于没有被访问过,就会被移动到后 1/4 的 Old Sublist中去,直到被清理掉。 Log Buffer Log Buffer 用来存储那些即将被刷入到磁盘文件中的日志,例如 Redo Log,该区域也是 InnoDB内存的重要组成部分。Log Buffer 的默认值为16M,如果我们需要进行调整的话,可以通过配置参数innodb_log_buffer_size来进行调整。 当 Log Buffer 如果较大,就可以存储更多的 Redo Log,这样一来在事务提交之前我们就不需要将 Redo Log 刷入磁盘,只需要丢到 Log Buffer 中去即可。因此较大的 Log Buffer 就可以更好的支持较大的事务运行;同理,如果有事务会大量的更新、插入或者删除行,那么适当的增大 Log Buffer 的大小,也可以有效的减少部分磁盘 I/O 操作。 至于 Log Buffer 中的数据刷入到磁盘的频率,则可以通过参数innodb_flush_log_at_trx_commit来决定。 本篇文章已放到我的 Github github.com/sh-blog 中,欢迎 Star。微信搜索关注【SH的全栈笔记】,回复【队列】获取MQ学习资料,包含基础概念解析和RocketMQ详细的源码解析,持续更新中。 如果你觉得这篇文章对你有帮助,还麻烦点个赞,关个注,分个享,留个言。

优秀的个人博客,低调大师

Redis入门|看这篇就够了!

2 --> Redis 是当今非常流行的基于 KV 结构的作为Cache 使用的 NoSQL数据库。 学习Redis最好的方法就是动手尝试,在介绍Redis核心内容之前,本篇文章主要先来介绍一下Redis的安装和使用,以及Redis的基础知识。 开始之前,分享给大家这套视频教程,在视频中能了解NoSQL是什么,NoSQL和关系型数据库的对比优缺点。掌握Redis是什么、能干什么、如何用;掌握Redis在Windows和Linux下的安装配置、五大数据类型、常用操作命令、Redis持久化、主从复制、事务控制以及用Jedis操作进行Java开发等技术点! 在线观看:https://www.bilibili.com/video/BV1Uz4y1X72A 资料下载:http://www.bjpowernode.com/javavideo/130.html Redis 介绍 Remote Dictionary Server(Redis)是一个开源的使用C 语言编写、支持网络、可基于内存亦可持久化的 Key-Value 数据库. Key 字符类型,其值(value)可以是字符串(String), 哈希(Map),列表(list), 集合(sets) 和有序集合(sorted sets)等类型,每种数据类型有自己的专属命令。所以它通常也被称为数据结构服务器。 Redis 的作者是 Antirez,来自意大利的西西里岛,现在居住在卡塔尼亚。目前供职于Pivotal 公司(Pivotal 是 Spring 框架的开发团队),Antirez 被称为 Redis 之父。 Redis的代码托管在GitHub上https://github.com/antirez/redis,开发十分活跃,代码量只有3万多行。 官网:https://redis.io/ 中文:http://www.redis.cn/ Window 上安装 Redis Windows 版本的 Redis 是 Microsoft 的开源部门提供的 Redis. 这个版本的 Redis 适合开发人员学习使用,生产环境中使用 Linux 系统上的 Redis (1) 下载 官网:https://redis.io/ windows 版本:https://github.com/MSOpenTech/redis/releases (2) 安装 下载的 Redis-x64-3.2.100.zip 解压后,放到某个目录(例如 d:\tools\),即可使用。目录结构: (3) 启动 1. Windows7 系统双击 redis-server.exe 启动 Redis 2. Windows 10 系统 有的机器双击 redis-server.exe 执行失败,找不到配置文件,可以采用以下执行方式: 在命令行(cmd)中按如下方式执行: D:\tools\Redis-x64-3.2.100>redis-server.exe redis.windows.conf 如图: (4) 关闭 按 ctrl+c 退出Redis 服务程序。 Linux 上安装 Redis (1) 安装 1. 上传 redis-4.0.13.tar.gz 到 linux 系统。使用 Xftp 工具 2. 解压 redis-4.0.13.tar.gz 到/usr/local 目录 3. 查看解压后的文件 切换目录 cd /usr/local 执行 ll 4. 安装 gcc 编译器 Redis 是使用 c 语言编写的。使用源文件安装方式,需要编译 c 源文件,会使用 gcc 编译器。 什么是 gcc ? gcc 是 GNU compiler collection 的缩写,它是 Linux 下一个编译器集合(相当于 javac ),是c 或 c++程序的编译器。 使用yum进行安装gcc 。执行命令:yum -y install gcc 在解压后的 Redis 目录下执行(cd /usr/local/redis-4.0.13) make 命令。 5. 编译 redis 源文件 1) 开始执行 make cd /usr/local/redis-4.0.13 再执行 make 如果 make 命令执行过程中出现错误: error: jemalloc/jemalloc.h: No such file or directory 解决方式执行 make MALLOC=libc 2)执行 make 成功的标志 3)查看make编译结果,cd src目录 cd src 在执行 ls (2) 启动 Redis redis 安装目录下 redis.conf 是重要的配置文件,包含 redis 服务器的配置信息。启动redis 需要指定配置文件路径。 启动方式: ①前台启动 ./redis-server redis.conf 配置文件路径 ②后台启动 ./redis-server redis.conf 配置文件路径 & 第①种 前台启动 启动 Redis 的服务器端:切换到 src 目录下执行redis-server 程序 或者使用全路径 redis 应用以前台的方式启动,不能退出当前窗口,退出窗口,应用终止。 在其他窗口查看redis 启动的进程 第②种 后台启动 src目录下执行 ./redis-server redis.conf配置文件路径 & 此时关闭窗口,查看redis进程,依然存在。 查看redis进程 (3) 关闭 Redis 关闭方式: ①使用 redis 客户端关闭,向服务器发出关闭命令 切换到 redis-4.0.13/src/ 目录,执行 ./redis-cli shutdown 推荐使用这种方式, redis 先完成数据操作,然后再关闭。 例如: ②kill pid 或者 kill -9 pid 这种不会考虑当前应用是否有数据正在执行操作,直接就关闭应用。先使用 ps -ef | grep redis 查出进程号,在使用 kill pid Redis 客户端 Redis 客户端是一个程序,通过网络连接到 Redis 服务器,在客户端软件中使用 Redis 可 以识别的命令,向 Redis 服务器发送命令,告诉 Redis 想要做什么。Redis 把处理结果显示在客户端界面上。通过 Redis 客户端和 Redis 服务器交互。 Redis 客户端发送命令,同时显示 Redis 服务器的处理结果在。 redis 命令行客户端: redis-cli(Redis Command Line Interface)是 Redis 自带的基于命令行的Redis 客户端,用于与服务端交互,我们可以使用该客户端来执行redis 的各种命令。 两种常用的连接方式: 1. 直接连接 redis (默认 ip127.0.0.1,端口 6379):./redis-cli 在 redis 安装目录/src,执行 ./redis-cli 此命令是连接本机 127.0.0.1 ,端口 6379 的 redis 2. 指定 IP 和端口连接 redis:./redis-cli -h 127.0.0.1 -p 6379 -h redis 主机 IP(可以指定任意的 redis 服务器) -p 端口号(不同的端口表示不同的redis 应用) 在 redis 安装目录/src,执行 ./redis-cli -h 127.0.0.1 -p 6379 例 1: redis 远程客户端 Redis Desktop Manager:C++ 编写,响应迅速,性能好。官网地址:https://redisdesktop.com/ 点击“DOWNLOAD” 1. 安装客户端软件 在 Windows 系统使用此工具,连接 Linux 上或 Windows 上的 Redis , 双击此exe 文件执行安装 安装后启动界面: 使用客户端连接 Linux 的 Redis 连接Linux的Reids之前需要修改Redis服务器的配置信息。 Redis服务器有安全保护措施,默认只有本机(安装Redis的那台机器)能够访问。配置信息存放在Redis安装目录下的redis.conf文件。修改此文件的两个设置。 远程连接redis需要修改redis主目录下的redis.conf配置文件: ①. bind ip 绑定ip此行注释 ②. protected-mode yes 保护模式改为 no 使用vim 命令修改redis.conf 文件,修改文件前备份此文件,执行 cp 命令 执行 vim redis.conf 3. 使用 redis.conf 启动 Redis 修改配置文件后,需要使用配置文件重新启动 Reids,默认不加载配置文件。先关闭已经启 动的 Redis ,使用以下命令启动 Redis 在 Redis 安装目录执行: ./redis-server ../redis.conf & 4. 关闭 Linux 系统的防火墙 linux 系统,命令行执行:systemctl stop firewalld 5. 配置 Redis Desktop Manamager(RDM),连接 Redis 在 RDM 的主窗口,点击左下的“Connect to Redis Server” 连接成功后: redis 编程客户端 Jedis redis 的 Java 编程客户端,Redis 官方首选推荐使用 Jedis,jedis 是一个很小但很健全的 redis 的 java 客户端。通过Jedis 可以像使用 Redis 命令行一样使用Redis。 jedis 完全兼容redis 2.8.x and 3.x.x Jedis 源码:https://github.com/xetorthio/jedis api 文档:http://xetorthio.github.io/jedis/ redis 的其他编程语言客户端: C 、C++ 、C# 、Erlang、Lua 、Objective-C、Perl 、PHP 、Python 、Ruby、Scala 、Go 等 40 多种语言都有连接redis 的编程客户端 Redis 基本操作命令 redis 默认为 16 个库 (在redis.conf 文件可配置,该文件很重要,后续很多操作都是这个配置文件) redis 默认自动使用 0 号库 (1) 沟通命令,查看状态 redis >ping 返回 PONG 解释:输入 ping,redis 给我们返回 PONG,表示 redis 服务运行正常 (2) 查看当前数据库中 key 的数目:dbsize 语法:dbsize 作用:返回当前数据库的 key 的数量。返回值:数字,key 的数量 例:先查索引 5 的 key 个数, 再查 0 库的 key 个数 (3) redis 默认使用 16 个库 Redis默认使用16个库,从0到15。 对数据库个数的修改,在redis.conf 文件中databases 16 (4) 切换库命令:select db 使用其他数据库,命令是 select index 例 1: select 5 (5) 删除当前库的数据:flushdb (6) redis 自带的客户端退出当前 redis 连接:exit 或 quit Redis 的Key 的操作命令 1. keys 语法:keys pattern 作用:查找所有符合模式 pattern 的 key. pattern 可以使用通配符。通配符: *:表示 0-多个字符,例如:keys * 查询所有的 key。 ?:表示单个字符,例如:wo?d , 匹配 word , wood 例 1:显示所有的 key 例 2:使用 *表示 0 或多个字符 例 3:使用?表示单个字符 2. exists 语法:exists key [key…] 作用:判断key 是否存在 返回值:整数,存在 key 返回 1,其他返回 0.使用多个 key,返回存在的key 的数量。 例 1:检查指定 key 是否存在 例 2:检查多个 key 3. expire 语法:expire key seconds 作用:设置key 的生存时间,超过时间,key 自动删除。单位是秒。返回值:设置成功返回数字 1,其他情况是 0 。 例 1:设置红灯的倒计时是 5 秒 4. ttl 语法:ttl key 作用:以秒为单位,返回 key 的剩余生存时间(ttl: time to live) 返回值: -1 :没有设置 key 的生存时间, key 永不过期。 -2:key 不存在 数字:key 的剩余时间,秒为单位 例 1:设置 redlight 的过期时间是 10,查看剩余时间 5. type 语法:type key 作用:查看key 所存储值的数据类型返回值:字符串表示的数据类型 none (key 不存在) string (字符串) list (列表) set (集合) zset (有序集) hash (哈希表) 例 1:查看存储字符串的 key:wood 例 2:查看不存在的key 6. del 语法:del key [key…] 作用:删除存在的key,不存在的key 忽略。返回值:数字,删除的 key 的数量。 例 1:删除指定的 key

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册