首页 文章 精选 留言 我的

精选列表

搜索[AIOps最佳实践],共10001篇文章
优秀的个人博客,低调大师

openGemini 性能调优之最佳实践

作者:饭饭 一、监控搭建 openGemini 测试版本:v1.2 1. 关键监控指标的选取 搭建⼀个好的监控系统可以更好地帮助我们去发现和定位问题,使⽤官⽅推荐的Gemix⼀键部署可以⾃动帮你搭建Grafana,并且官⽅提供很详细的监控模板,可以接⼊openGemini的监控。 手动搭建参考:如何快速搭建openGemini运行状态的实时监控系统 监控模板: https://github.com/openGemini/gemix/tree/main/embed/templates/dashboards 以下⼏个点是出现写⼊异常能最直观快速发现异常点的⼏个关键监控数据 系统类:CPU、内存、磁盘容量、磁盘IO 读写类:集群流量、store写并发、SQL/Store写延迟、写Wal时延、SQL/Store写QPS、写Memtable时延 压缩合并类:乱序时间线占⽐、平均乱序⽂件、Compact耗时、乱序合并耗时、乱序⽂件总数 2. 异常指标样例 异常的写⼊曲线: 异常曲线不论是sql还是store,写流量的波峰和波⾕浮动很⼤,并且不论是sql、store、wal写时延都⾮常的⾼,这就代表写⼊有很⼤部分的时间在阻塞,性能遇到了瓶颈,需要我们进⾏优化。 ⽽正常的写⼊曲线是⼀个很平稳很稳定的⼀条线: 二、client端写入优化 1. Tag的选择 尽量选择平稳和基数少的指标作为你的Tag。 基数少:如果Tag基数过⼤会影响写⼊和查询效率,并且如果是多个Tag的模式会导致时间线以成倍的数量暴增。所以在选取字段做Tag的时候要考虑基数问题。 平稳:通常设备id或者传感器id⼀旦上线,不会在短时间内出现⼤量新tag的插⼊。所以在选择tag的时候也要考虑不能频繁的更新和插⼊新的Tag。 2. ts-sql负载均衡 有两种选择,一种是使用代理,另一种为SDK自带的负载均衡功能。 使⽤代理: 使⽤Nginx、云上弹性负载服ELB或者其它负载均衡器在ts-sql上做⼀层代理,使得与openGemini的请求能平均的请求到tssql节点上,避免单ts-sql成为性能瓶颈。 使⽤社区开源SDK: openGemini官方自研的SDK全部规划了负载均衡功能,但目前仅Go-Client已发布了版本。其他语言还在开发中。若使用InfluxDB 的SDK,需要自己实现。 所以不管使⽤哪种⼯具,最终的结果就是要请求平均访问带每个ts-sql上: 值得注意的是,当你引入负载均衡器,其实相当于引入一个新的组件,所以引入的负载均衡器的性能也有可能导致写入变慢或者不稳定,所以可以重点关注如下一些指标: 将负载均衡器的空闲超时时间、响应超时时间、请求超时时间尽可能的调大,增加容错率 查看并发链接数是否达到上限 查看入网和出网带宽是否达到上限,我就因为负载均衡器的入网带宽出现瓶颈,导致TS-SQL的写延迟非常大,导致写入的速率和稳定性变差。 3. INSETBATCHSIZE参数配置 批量写入是提升数据写入效率的最直接方法,但并非单批次写入的数据越多越好,因为数据库的处理能力是一定的。然而硬件配置的不同,往往无法给出具体的Batchsize大小建议。 Insert Batchsize大小配置: 不论是Influx-java还是社区的opengemini-client,都提供了批量提交参数 batchsize 和 flushDuration,根据每行的列数和数据量可以多次尝试一个合适的batchsize来实现写入性能的最优,如果列很多,不推荐每批写入数据的过多,batchsize一般设置为500,800,1000,2000,4000进行尝试,来选取最适合自己的写入批次。 开启压缩: 开启压缩在大批量数据写入的时候有可能也可以提升写的效率,influx-java通过influxDB.enableGzip();开启写入压缩。 三、Wal写⼊瓶颈 使用了官方默认参数开始压测写入数据,然后观察写入指标是否正常,主要观察如下几个指标: cpu & 内存使用率 sql & store写流量 sql & store写时延 一开始表现为写时延非常的高,并且伴随着写流量波动非常大 其实写流量波动和写时延是息息相关的,写时延小自然写流量就稳定,写时延大自然写流量波动就大。 客户端报的错也都是select timeout in 10s seconds 或者 timeout超时的错误提示,所以第一时间想到的就是修改shard-writer-timeout等类似超时参数,其实这就步入了一个误区,当你的集群吞吐上不去的时候,超时参数改的再大只能增加集群的容错性,最终因为集群吞吐量和集群io跟不上报超时异常也只是时间早晚的问题,不能从根本去解决问题。 最后通过观察指标发现写wal的时延异常的高: WAL是openGemini在写入业务数据之前的预写日志,为了防止服务器宕机或者进行异常退出的时候数据丢失而做的可靠性策略。 而写入一条数据的时延 = 写wal时延 + 写store时延。比如写wal耗时2s,写store时延80μs,那么些一条数据的耗时就是2s + 80μs,数据写入是串行进行的,先写wal,在写store,所以写Wal耗时过高是一种非常影响写性能的一个现象。 所以下面有两种方案可以对此现象进行优化: 1. 关闭WAL,验证瓶颈点 修改ts-store的data配置 [data]wal-enabled = false 关闭wal之后,wal时延监控一栏时间明显大幅度降低,并且sql和store写入时延降低,写入速率变得平稳,由此可以判断引起写入波动的原因是在WAL这里。 2. WAL文件目录单独挂盘 作为保证数据不丢失的重要功能,基本上都会开启Wal功能,开启Wal的情况下,建议如下:​​​​​​ [data]wal-enabled = truestore-data-dir = ""store-wal-dir = "" 因为我们store盘的I/O是非常强大的,并且性能没有拉满,所以当时的想法就是store和wal共用一块磁盘。但是实际效果不是很理想,但是通过监控发现其实磁盘的写入速率还有I/O都不存在任何瓶颈,但是为啥速率上不去呢。 因为wal和store数据如果共用一块盘,在大量写入数据的时候,WAL和数据都会频繁写文件,存在磁盘I/O竞争关系,磁盘需要在两个请求之间来回切换,所以同样也会导致wal写入过慢,从而整体影响store的写入时延。 所以store-data-dir 和 store-wal-dir的写入磁盘强烈建议分开,就算你的一块磁盘的性能还剩余很多,也强烈不建议把store-data-dir 和 store-wal-dir放在一个磁盘路径下。 因为数据写入时延 = 写wal时延 + 写store时延,所以在store时延固定的情况下,同样建议wal写入的磁盘同样使用高I/O高性能磁盘降低wal写入时延,从而降低数据写入时延。 四、磁盘io瓶颈 Wal时延优化了之后,随着进行数据量的不断压测,写store的时延还在持续增加,写入波动持续增大,但是机器的cpu和内存还有盈余,这时候就考虑是store所在磁盘I/O的瓶颈。 磁盘的I/O使用率一直在100%左右徘徊,解决这个问题也很简单,把Store的写磁盘直接上高吞吐量,使用高I/O的硬盘。 五、内存配置 & 吞吐量调优 Wal瓶颈和磁盘I/O瓶颈解决之后,在一定数据量范围内可以写入平稳,但是内存和cpu仍然没有完全使用,并且稍微数据量稍微再上调一点就变得十分不稳定。 因为Wal写时延和store写时延我们通过上述调优已经非常完美了,所以这时候就考虑是不是openGemini的默认参数,比如内存,吞吐量配置和我们集群规模不匹配导致集群不能充分发挥他的特性。 当前虚拟机规格为16U64GB,经过与社区的沟通和讨论,将参数做出如下的修改: shard-mutable-size-limit = "1g" 单个shard中写数据缓存大小限制上调到1GB,默认值: memorySize/256,并强制介于 8MB - 1GB 之间。 node-mutable-size-limit = "16g" 节点中写数据缓存大小限制上调到16GB,默认值: memory-size/16,并强制介于 32MB - 16GB 之间。 snapshot-throughput = "300m" snapshot-throughput-burst = "300m" 缓存加大,需要随之调整系统刷盘带宽,否则依然不起作用。写数据流程是先写wal然后写mutable,再等待刷盘,snapshot-*参数负责数据刷盘的流控,控制磁盘I/O带宽的,当前上调到300MB。 因为我们集群内存比较充裕,并且磁盘I/O还有盈余,所以我们配置的值都是比较大的,可以根据大家自己的集群规模可以适当的更改。 平稳写入曲线有了质的提升,平稳写入速率大约提升了一倍多,目的达到。 六、compact参数调优 openGemini的compaction分为普通level compaction和full compaction,前者是在数据一边写入一边工作,而full compaction则是超过一定时间没写数据就会触发,或者在业务低峰时触发。 #compact吞吐量。 compact-throughput="300m" #compact吞吐量突发。 compact-throughput-burst="300m" 数据量大的情况下,会频繁的进行level compaction,增大compaction的吞吐量就可以减少compaction的耗时,相应的提升集群的吞吐量。 compact耗时下降,速度有一定的提升并且更加稳定了些。 七、乱序数据处理 当停止写入数据并且确认SQL端和Store端写请求为0的时候发现数据磁盘IO一直处于40%左右的繁忙状态,那么只有可能是openGemini系统再做操作,那就只可能是压缩数据的compaction操作和乱序数据的merge操作。但是经过compaction的监控数据发现数据停止写入大概几小时后就会停止compaction操作,所以定位到该操作就是乱序merge引起的。 针对乱序数据的解决方案: 1、确保单条时间线数据是有序的,比如tag作为key插入kafka当中保证单tag数据在单partition的有序性。并且每次批量插入数据时保证批量数据局部有序,这样可以最大程度减少乱序文件数量。 什么是时间线?参考: https://docs.opengemini.org/zh/guide/reference/specification.html 2、因为乱序数据合并会占磁盘I/O,如果业务上面是在无法去除乱序数据,可以采用高I/O磁盘来削平合并乱序数据对磁盘I/O产生的影响 3、升级openGemini的版本,v1.2 版本针对内核进行了优化,经过测试也会针对乱序数据的处理提升了效率,并且社区表示后续的版本也会针对compaction和merge操作进行更深层次的优化。 八、集群规模更改 假设我一个集群是10台16U64G,那么我换成20台8U32G,那么我整个的集群吞吐效率是否会有提升呢? 首先说下为什么会有这么一个想法: 衡量一台机器性能无非就是内存,CPU和磁盘I/O,但是经过多次实验发现每次最先达到瓶颈的是磁盘I/O,但是又不想上成本非常昂贵的高I/O磁盘,那么我们是不是可以降低单台机器性能 + 相对中等的I/O磁盘,增加节点数来扩充集群吞吐呢? 这么做从理论上有这么几点好处: 1、节点增多意味着单时间范围shard增多,增多节点意味着写的并行度增大 2、节点增多,意味着在总请求不变的情况下,每个节点处理的写请求变小,也有益于提升写入效率 3、并且大机器分为两个小机器,磁盘用稍微逊色的I/O磁盘,机器成本是降低的 经过多次实验写入也发现,适当的调整集群规模,在集群总cpu和内存不变的情况下用多机器代替高性能少机器其实对写入的效率也会有很大的提升。 结束 本文主要介绍了我在使用openGemini进行性能调优过程中的一些做法。在海量数据写入场景下实测,通过适当的参数优化,openGemini是完全可以满足性能要求,并且openGemini的内存控制的非常好,希望可以给大家做参考 openGemini官网:http://www.openGemini.org Star for me😊:https://github.com/openGemini openGemini公众号: 欢迎关注~ 诚邀你加入 openGemini 社区,共建、共治、共享未来!

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

Solon Web 文件上传(upload)的最佳实践

1、如果是高频且文件极小 使用“纯内存模式”,即默认。如果高频小文件,应该是不适合用“临时文件模式”的,磁盘可能容易刷坏。只能多配些内存! 2、如果是低频或者文件很大 建议使用“临时文件模式”。即上传的文件数据流,先缓存为临时文件,再以文件流形式提供使用。这个非常省内存。比如,上传 1GB 的文件,服务内存几乎不会上升。 a) 添加配置 server.request.useTempfile: true #默认 false b) 用后主动删除(建议,不管有没有用“临时文件模式”都主动删除。方便随时切换) 使用完后,注意要删掉(框架不会自动删除)。如果等操作系统自动删除临时文件可能磁盘要暴掉了。 @Controller public class DemoController{ @Post @Mapping("/upload") public void upload(UploadedFile file) { try{ //可以同步处理,也可以异步 file.transferTo(new File("/demo/user/logo.jpg")); } finally { //用完之后,删除"可能的"临时文件 //v2.7.2 后支持 file.delete(); } } } 关于 useTempfile 的配置支持情况: 插件 情况 solon.boot.jdkhttp 支持 solon.boot.jlhttp 支持 solon.boot.smarthttp 支持 solon.boot.jetty 支持 solon.boot.undertow 不支持(强制使用临时文件模式) c) 使用过滤器实现自动删除(文件处理不能为异步,否则提前就删没了) public class FileDeleteFilter implements Filter { @Override public void doFilter(Context ctx, FilterChain chain) throws Throwable { chain.doFilter(ctx); if (ctx.isMultipartFormData()) { //批量删除临时文件 for (List<UploadedFile> files : ctx.filesMap().values()) { for (UploadedFile file : files) { file.delete(); } } } } }

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

Git 入门最佳实践

点击上方“民工哥技术之路”,选择“设为星标” 回复“1024”获取独家整理的学习资料! Git简介 Git 是一种分布式版本控制系统,它可以不受网络连接的限制,加上其它众多优点,目前已经成为程序开发人员做项目版本管理时的首选,非开发人员也可以用 Git 来做自己的文档版本管理工具。 2013年,淘宝前端团队开始全面采用 Git 来做项目管理,我也是那个时候开始接触和使用,从一开始的零接触到现在的重度依赖,真是感叹 Git 的强大。 Git 的api很多,但其实平时项目中90%的需求都只需要用到几个基本的功能即可,所以本文将从 实用主义 和 深入探索 2个方面去谈谈如何在项目中使用 Git,一般来说,看完 实用主义 这一节就可以开始在项目中动手用。 说明:本文的操作都是基于 Mac 系统 准备阶段 进入 Git官网下载合适你的安装包,当前我下载到的版本是 2.11.0,本文也将在这个版本上演示效果。安装好 Git 后,打开命令行工具,进入工作文件夹(为了便于理解我们在系统桌面上演示),创建一个新的demo文件夹。进入 Github网站 注册一个账号并登录,进入: https://github.com/gafish/gafish.github.com 点击 Clone or download ,再点击 Use HTTPS,复制项目地址 : https://github.com/gafish/gafish.github.com.git 备用。 再回到命令行工具,一切就绪,接下来进入本文的重点。 常用操作 所谓实用主义,就是掌握了以下知识就可以玩转 Git,轻松应对90%以上的需求。以下是实用主义型的Git命令列表,先大致看一下 gitclonegitconfiggitbranchgitcheckoutgitstatusgitaddgitcommitgitpushgitpullgitloggittag 接下来,将通过对:https://github.com/gafish/gafish.github.com 仓库进行实例操作,讲解如何使用 Git 拉取代码到提交代码的整个流程。 git clone 从git服务器拉取代码 gitclonehttps://github.com/gafish/gafish.github.com.git 代码下载完成后在当前文件夹中会有一个 gafish.github.com 的目录,通过 cd gafish.github.com 命令进入目录。 git config 配置开发者用户名和邮箱 gitconfiguser.namegafishgitconfiguser.emailgafish@qqqq.com 每次代码提交的时候都会生成一条提交记录,其中会包含当前配置的用户名和邮箱。 git branch 创建、重命名、查看、删除项目分支,通过 Git 做项目开发时,一般都是在开发分支中进行,开发完成后合并分支到主干。 gitbranchdaily/0.0.0 创建一个名为 daily/0.0.0 的日常开发分支,分支名只要不包括特殊字符即可。 gitbranch-mdaily/0.0.0daily/0.0.1 如果觉得之前的分支名不合适,可以为新建的分支重命名,重命名分支名为 daily/0.0.1 git branch 通过不带参数的branch命令可以查看当前项目分支列表 gitbranch-ddaily/0.0.1 如果分支已经完成使命则可以通过 -d 参数将分支删除,这里为了继续下一步操作,暂不执行删除操作 git checkout 切换分支 gitcheckoutdaily/0.0.1 切换到 daily/0.0.1 分支,后续的操作将在这个分支上进行 git status 查看文件变动状态 通过任何你喜欢的编辑器对项目中的 README.md 文件做一些改动,保存。 git status 通过 git status 命令可以看到文件当前状态 Changes not staged for commit: (改动文件未提交到暂存区) Onbranchdaily/0.0.1Changesnotstagedforcommit:(use"gitadd<file>..."toupdatewhatwillbecommitted)(use"gitcheckout--<file>..."todiscardchangesinworkingdirectory)modified:README.mdnochangesaddedtocommit(use"gitadd"and/or"gitcommit-a")gitadd 添加文件变动到暂存区 gitaddREADME.md 通过指定文件名 README.md 可以将该文件添加到暂存区,如果想添加所有文件可用 git add . 命令,这时候可通过 git status 看到文件当前状态 Changes to be committed: (文件已提交到暂存区) Onbranchdaily/0.0.1Changestobecommitted:(use"gitresetHEAD<file>..."tounstage)modified:README.md git commit 提交文件变动到版本库 gitcommit-m'这里写提交原因' 通过 -m 参数可直接在命令行里输入提交描述文本 git push 将本地的代码改动推送到服务器 gitpushorigindaily/0.0.1 origin 指代的是当前的git服务器地址,这行命令的意思是把 daily/0.0.1 分支推送到服务器,当看到命令行返回如下字符表示推送成功了。 Countingobjects:3,done.Deltacompressionusingupto8threads.Compressingobjects:100%(2/2),done.Writingobjects:100%(3/3),267bytes|0bytes/s,done.Total3(delta1),reused0(delta0)remote:Resolvingdeltas:100%(1/1),completedwith1localobjects.Tohttps://github.com/gafish/gafish.github.com.git*[newbranch]daily/0.0.1->daily/0.0.1 现在我们回到Github网站的项目首页,点击 Branch:master 下拉按钮,就会看到刚才推送的 daily/00.1分支了 git pull 将服务器上的最新代码拉取到本地 gitpullorigindaily/0.0.1 如果其它项目成员对项目做了改动并推送到服务器,我们需要将最新的改动更新到本地,这里我们来模拟一下这种情况。 进入Github网站的项目首页,再进入 daily/0.0.1 分支,在线对 README.md 文件做一些修改并保存,然后在命令中执行以上命令,它将把刚才在线修改的部分拉取到本地,用编辑器打开 README.md ,你会发现文件已经跟线上的内容同步了。 如果线上代码做了变动,而你本地的代码也有变动,拉取的代码就有可能会跟你本地的改动冲突,一般情况下 Git 会自动处理这种冲突合并,但如果改动的是同一行,那就需要手动来合并代码,编辑文件,保存最新的改动,再通过 git add . 和 git commit -m 'xxx' 来提交合并。 git log 查看版本提交记录 gitlog 通过以上命令,我们可以查看整个项目的版本提交记录,它里面包含了提交人、日期、提交原因等信息,得到的结果如下: commitc334730f8dba5096c54c8ac04fdc2b31ede7107aAuthor:gafish<gafish@qqqq.com>Date:WedJan1109:44:132017+0800UpdateREADME.mdcommitba6e3d21fcb1c87a718d2a73cdd11261eb672b2aAuthor:gafish<gafish@qqqq.com>Date:WedJan1109:31:332017+0800test..... 提交记录可能会非常多,按 J 键往下翻,按 K 键往上翻,按 Q 键退出查看 git tag 为项目标记里程碑 gittagpublish/0.0.1gitpushoriginpublish/0.0.1 当我们完成某个功能需求准备发布上线时,应该将此次完整的项目代码做个标记,并将这个标记好的版本发布到线上,这里我们以 publish/0.0.1 为标记名并发布,当看到命令行返回如下内容则表示发布成功了 Total0(delta0),reused0(delta0)Tohttps://github.com/gafish/gafish.github.com.git*[newtag]publish/0.0.1->publish/0.0.1.gitignore 设置哪些内容不需要推送到服务器,这是一个配置文件 touch.gitignore .gitignore 不是 Git 命令,而在项目中的一个文件,通过设置 .gitignore 的内容告诉 Git 哪些文件应该被忽略不需要推送到服务器,通过以上命令可以创建一个 .gitignore 文件,并在编辑器中打开文件,每一行代表一个要忽略的文件或目录,如: demo.htmlbuild/ 以上内容的意思是 Git 将忽略 demo.html 文件 和 build/ 目录,这些内容不会被推送到服务器上 小结 通过掌握以上这些基本命令就可以在项目中开始用起来了,如果追求实用,那关于 Git 的学习就可以到此结束了,偶尔遇到的问题也基本上通过 Google 也能找到答案,如果想深入探索 Git 的高阶功能,那就继续往下看 深入探索 部分。 深入探索 基本概念 工作区(Working Directory) 就是你在电脑里能看到的目录,比如上文中的 gafish.github.com 文件夹就是一个工作区 本地版本库(Local Repository) 工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。 暂存区(stage) 本地版本库里存了很多东西,其中最重要的就是称为 stage(或者叫index)的暂存区,还有 Git 为我们自动创建的第一个分支 master,以及指向 master 的一个指针叫 HEAD。 远程版本库(Remote Repository) 一般指的是 Git 服务器上所对应的仓库,本文的示例所在的github仓库就是一个远程版本库 以上概念之间的关系:工作区、暂存区、本地版本库、远程版本库之间几个常用的 Git 操作流程如下图所示: 分支(Branch) 分支是为了将修改记录的整个流程分开存储,让分开的分支不受其它分支的影响,所以在同一个数据库里可以同时进行多个不同的修改 主分支(Master)前面提到过 master 是 Git 为我们自动创建的第一个分支,也叫主分支,其它分支开发完成后都要合并到 master标签(Tag) 标签是用于标记特定的点或提交的历史,通常会用来标记发布版本的名称或版本号(如:publish/0.0.1),虽然标签看起来有点像分支,但打上标签的提交是固定的,不能随意的改动,参见上图中的1.0 / 2.0 / 3.0 HEAD HEAD 指向的就是当前分支的最新提交 以上概念了解的差不多,那就可以继续往下看,下面将以具体的操作类型来讲解 Git 的高阶用法 操作文件 gitadd#添加文件到暂存区gitadd-i#通过此命令将打开交互式子命令系统,你将看到如下子命令***Commands***1:status2:update3:revert4:adduntracked5:patch6:diff7:quit8:help 通过输入序列号或首字母可以选择相应的功能,具体的功能解释如下: status:#功能上和gitadd-i相似,没什么鸟用update:#详见下方gitadd-urevert:#把已经添加到暂存区的文件从暂存区剔除,其操作方式和update类似add untracked:#可以把新增的文件添加到暂存区,其操作方式和update类似patch:#详见下方gitadd-pdiff:#比较暂存区文件和本地版本库的差异,其操作方式和update类似quit:#退出gitadd-i命令系统help:#查看帮助信息 gitadd-p 直接进入交互命令中最有用的 patch 模式 这是交互命令中最有用的模式,其操作方式和 update 类似,选择后 Git 会显示这些文件的当前内容与本地版本库中的差异,然后您可以自己决定是否添加这些修改到暂存区,在命令行 Stage deletion [y,n,q,a,d,/,?]? 后输入 y,n,q,a,d,/,? 其中一项选择操作方式,具体功能解释如下: y:接受修改 n:忽略修改 q:退出当前命令 a:添加修改 d:放弃修改 /:通过正则表达式匹配修改内容 ?:查看帮助信息 gitadd-u 直接进入交互命令中的 update 模式 它会先列出工作区 修改 或 删除 的文件列表,新增 的文件不会被显示,在命令行 Update>> 后输入相应的列表序列号表示选中该项,回车继续选择,如果已选好,直接回车回到命令主界面 gitadd--ignore-removal.#添加工作区修改或新增的文件列表,删除的文件不会被添加gitcommit#把暂存区的文件提交到本地版本库gitcommit-m'第一行提交原因'-m'第二行提交原因'#不打开编辑器,直接在命令行中输入多行提交原因gitcommit-am'提交原因'#将工作区修改或删除的文件提交到本地版本库,新增的文件不会被提交gitcommit--amend-m'提交原因'#修改最新一条提交记录的提交原因gitcommit-CHEAD#将当前文件改动提交到HEAD或当前分支的历史IDgitmv#移动或重命名文件、目录gitmva.mdb.md-f#将a.md重命名为b.md,同时添加变动到暂存区,加-f参数可以强制重命名,相比用mva.mdb.md命令省去了gitadd操作gitrm#从工作区和暂存区移除文件gitrmb.md#从工作区和暂存区移除文件b.md,同时添加变动到暂存区,相比用rmb.md命令省去了gitadd操作gitrmsrc/-r#允许从工作区和暂存区移除目录gitstatusgitstatus-s#以简短方式查看工作区和暂存区文件状态,示例如下:Mdemo.html??test.htmlgitstatus--ignored#查看工作区和暂存区文件状态,包括被忽略的文件 操作分支 gitbranch#查看、创建、删除分支gitbranch-a#查看本地版本库和远程版本库上的分支列表gitbranch-r#查看远程版本库上的分支列表,加上-d参数可以删除远程版本库上的分支gitbranch-D#分支未提交到本地版本库前强制删除分支gitbranch-vv#查看带有最后提交id、最近提交原因等信息的本地版本库分支列表 gitmerge#将其它分支合并到当前分支gitmerge--squash#将待合并分支上的commit合并成一个新的commit放入当前分支,适用于待合并分支的提交记录不需要保留的情况 gitmerge--no-ff#默认情况下,Git 执行"快进式合并"(fast-farward merge),会直接将 Master 分支指向 Develop 分支,使用--no-ff 参数后,会执行正常合并,在 Master 分支上生成一个新节点,保证版本演进更清晰。 gitmerge--no-edit#在没有冲突的情况下合并,不想手动编辑提交原因,而是用Git自动生成的类似Mergebranch'test'的文字直接提交gitcheckout#切换分支gitcheckout-bdaily/0.0.1#创建daily/0.0.1分支,同时切换到这个新创建的分支gitcheckoutHEADdemo.html#从本地版本库的HEAD(也可以是提交ID、分支名、Tag名)历史中检出demo.html覆盖当前工作区的文件,如果省略HEAD则是从暂存区检出gitcheckout--orphannew_branch#这个命令会创建一个全新的,完全没有历史记录的新分支,但当前源分支上所有的最新文件都还在,真是强迫症患者的福音,但这个新分支必须做一次 git commit 操作后才会真正成为一个新分支。gitcheckout-pother_branch#这个命令主要用来比较两个分支间的差异内容,并提供交互式的界面来选择进一步的操作,这个命令不仅可以比较两个分支间的差异,还可以比较单个文件的差异。gitstash#在 Git 的栈中保存当前修改或删除的工作进度,当你在一个分支里做某项功能开发时,接到通知把昨天已经测试完没问题的代码发布到线上,但这时你已经在这个分支里加入了其它未提交的代码,这个时候就可以把这些未提交的代码存到栈里。gitstash#将未提交的文件保存到Git栈中gitstashlist#查看栈中保存的列表gitstashshowstash@{0}#显示栈中其中一条记录gitstashdropstash@{0}#移除栈中其中一条记录gitstashpop#从Git栈中检出最新保存的一条记录,并将它从栈中移除gitstashapplystash@{0}#从Git栈中检出其中一条记录,但不从栈中移除gitstashbranchnew_banch#把当前栈中最近一次记录检出并创建一个新分支gitstashclear#清空栈里的所有记录gitstashcreate#为当前修改或删除的文件创建一个自定义的栈并返回一个ID,此时并未真正存储到栈里gitstashstorexxxxxx#将create方法里返回的ID放到store后面,此时在栈里真正创建了一个记录,但当前修改或删除的文件并未从工作区移除$gitstashcreate09eb9a97ad632d0825be1ece361936d1d0bdb5c7$gitstashstore09eb9a97ad632d0825be1ece361936d1d0bdb5c7$gitstashliststash@{0}:Createdvia"gitstashstore". 操作历史 gitlog#显示提交历史记录gitlog-p#显示带提交差异对比的历史记录gitlogdemo.html#显示demo.html文件的历史记录gitlog--since="2weeksago"#显示2周前开始到现在的历史记录,其它时间可以类推gitlog--before="2weeksago"#显示截止到2周前的历史记录,其它时间可以类推gitlog-10#显示最近10条历史记录gitlogf5f630a..HEAD#显示从提交IDf5f630a到HEAD之间的记录,HEAD可以为空或其它提交IDgitlog--pretty=oneline#在一行中输出简短的历史记录gitlog--pretty=format:"%h"#格式化输出历史记录 Git 用各种 placeholder 来决定各种显示内容,我挑几个常用的显示如下: %H:#commithash%h:#缩短的commithash%T:#treehash%t:#缩短的treehash%P:#parenthashes%p:#缩短的parenthashes%an:#作者名字%aN:#mailmap的作者名%ae:#作者邮箱%ad:#日期(--date=制定的格式)%ar:#日期,相对格式(1dayago)%cn:#提交者名字%ce:#提交者email%cd:#提交日期(--date=制定的格式)%cr:#提交日期,相对格式(1dayago)%d:#ref名称%s:#commit信息标题%b:#commit信息内容%n:#换行 gitcherry-pick#合并分支的一条或几条提交记录到当前分支末梢gitcherry-pick170a305#合并提交ID170a305到当前分支末梢gitreset#将当前的分支重设(reset)到指定的<commit>或者HEADgitreset--mixed<commit>#--mixed是不带参数时的默认参数,它退回到某个版本,保留文件内容,回退提交历史gitreset--soft<commit>#暂存区和工作区中的内容不作任何改变,仅仅把HEAD指向<commit>gitreset--hard<commit>#自从<commit>以来在工作区中的任何改变都被丢弃,并把HEAD指向<commit>gitrebase#重新定义分支的版本库状态gitrebasebranch_name#合并分支,这跟 merge 很像,但还是有本质区别,看下图: 合并过程中可能需要先解决冲突,然后执行 git rebase --continue gitrebase-iHEAD~~#打开文本编辑器,将看到从HEAD到HEAD~~的提交如下pick9a54fd4添加commit的说明pick0d4a808添加pull的说明#Rebase326fc9f..0d4a808ontod286baa##Commands:#p,pick=usecommit#r,reword=usecommit,buteditthecommitmessage#e,edit=usecommit,butstopforamending#s,squash=usecommit,butmeldintopreviouscommit#f,fixup=like"squash",butdiscardthiscommit'slogmessage#x,exec=runcommand(therestoftheline)usingshell# 将第一行的 pick 改成 Commands 中所列出来的命令,然后保存并退出,所对应的修改将会生效。 如果移动提交记录的顺序,将改变历史记录中的排序。 gitrevert#撤销某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销作为一次最新的提交gitrevertHEAD#撤销前一次提交操作gitrevertHEAD--no-edit#撤销前一次提交操作,并以默认的Revert"xxx"为提交原因gitrevert-nHEAD#需要撤销多次操作的时候加-n参数,这样不会每次撤销操作都提交,而是等所有撤销都完成后一起提交gitdiff#查看工作区、暂存区、本地版本库之间的文件差异,用一张图来解释 gitdiff--stat#通过--stat参数可以查看变更统计数据test.md|1-1filechanged,1deletion(-)gitreflog#reflog可以查看所有分支的所有操作记录(包括commit和reset的操作、已经被删除的commit记录,跟gitlog的区别在于它不能查看已经删除了的commit记录 远程版本库连接 如果在GitHub项目初始化之前,文件已经存在于本地目录中,那可以在本地初始化本地版本库,再将本地版本库跟远程版本库连接起来 gitinit#在本地目录内部会生成.git文件夹gitremote-v#不带参数,列出已经存在的远程分支,加上-v列出详细信息,在每一个名字后面列出其远程urlgitremoteaddoriginhttps://github.com/gafish/gafish.github.com.git#添加一个新的远程仓库,指定一个名字,以便引用后面带的URLgitfetch#将远程版本库的更新取回到本地版本库gitfetchorigindaily/0.0.1#默认情况下,git fetch 取回所有分支的更新。如果只想取回特定分支的更新,可以指定分支名。 问题排查 gitblame#查看文件每行代码块的历史信息gitblame-L1,10demo.html#截取demo.html文件1-10行历史信息gitbisect#二分查找历史记录,排查BUGgitbisectstart#开始二分查找gitbisectbad#标记当前二分提交ID为有问题的点gitbisectgood#标记当前二分提交ID为没问题的点gitbisectreset#查到有问题的提交ID后回到原分支 更多操作 gitsubmodule#通过Git子模块可以跟踪外部版本库,它允许在某一版本库中再存储另一版本库,并且能够保持2个版本库完全独立gitsubmoduleaddhttps://github.com/gafish/demo.gitdemo#将demo仓库添加为子模块gitsubmoduleupdatedemo#更新子模块demogitgc#运行Git的垃圾回收功能,清理冗余的历史快照gitarchive#将加了tag的某个版本打包提取gitarchive-v--format=zipv0.1>v0.1.zip#--format 表示打包的格式,如 zip,-v 表示对应的tag名,后面跟的是tag名,如 v0.1。 总结 本文只是对 Git 的所有功能中的部分实用功能做了一次探秘,Git非常强大,还有很多功能有待我们去发现,限于本文篇幅,咱就此打住吧,预知更多好用功能,请善用谷歌。 转自:gafish 链接:https://github.com/gafish/gafish.github.com 推荐阅读点击标题可跳转 这款老牌国产软件,凉了!!! 刚刚,美团道歉了! 2021 年第一天,华为跟腾讯“干起来”了。。 彻底炸锅!比特币突破3万美元大关,100元狂赚12亿! 审计 Linux 系统的操作行为的 5 种方案对比 每天学一个 Linux 命令(15):man Git重磅推荐!5 款强大的开源报表工具 你知道吗?du 和 df 的统计结果为什么不一样 本文分享自微信公众号 - 民工哥技术之路(jishuroad)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

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

阿里云多账号网络互通最佳实践

前言 在企业起步阶段,规模较小,一般采用单账号模式。随着企业的发展,单账号的缺陷越来越明显,多账号相对于单账号有众多优点:• 多账号间的资源默认隔离,减少了单账号因为一个资源或服务问题导致其它资源和服务也出现问题的可能性;• 多账号减少了单帐户过于宽泛的 RAM 权限带来的风险;• 多账号便于成本结算、独立管理、环境隔离等。 因此中大型企业上云时通常选择多账号,但是多账号间往往存在着大量的网络互通场景,如何解决多账号的网络互通问题呢?VPC 作为云上最常用的网络环境,不同账号的 VPC 之间默认是无法互通的,多账号网络互通常用的解决方案是 CEN(云企业网)和 VPN 网关。 基于 VPN 的网络架构 VPN 网关是一款基于 Internet 的网络连接服务,通过加密通道的方式实现企业数据中心、企业办公网络或 Internet 终端与 VPC 安全可靠的连接。VPN 网关可以实现跨地域、跨账号的 VPC 互通,在需要连接的 VPC 上创建 VPN 网关,网关之间通过基于 Internet 的 IPSec 加密隧道来传输私网数据,以实现安全可靠的多账号 VPC 间通信。 图1 如上图所示:服务分别部署在账号1、2、3的 VPC 网络环境中,每个服务基于多可用区和 SLB 实现同城双活,前端 VPC 部署前端服务,后端 VPC 部署后端应用,前端服务处理 Web 请求时需调用部署在账号2、账号 3 的后端应用,分别为每个 VPC 创建 VPN网关,VPN 之间配置 IPSEC、路由,以此来实现多账号网络互通。 基于 CEN 的网络架构 云企业网(Cloud Enterprise Network)是承载在阿里云提供的高性能、低延迟的私有全球网络上的一张高可用网络,可以在跨地域、跨账号的 VPC 间搭建私网通道,通过自动路由分发及学习,提高网络的快速收敛和跨网络通信的质量和安全性,实现全网资源的互通,打造一张具有企业级规模和通信能力的互联网络。 图2 如上图所示:首先创建 CEN 实例,将要互通的网络实例(专有网络和边界路由器)加载到 CEN 中,再购买一个带宽包(同 Region 无需购买带宽包),配置路由、跨账号授权等,即可实现服务在不同账号的 VPC 间互通。 VPN 和 CEN 网络架构比较 VPN 和 CEN 都可实现多账号网络互通,两者有何区别呢?• VPN 需要为每个 VPC 配置 VPN 网关,创建 IPsec 连接、配置 VPN 网关路由等,随着 VPC 数量的增加,人工配置成本成倍增加;同时 VPN 连接使用共享的公网资源进行通信,网络延时和丢包率等都无法保证,其网络带宽受限于公网 IP 的带宽。在实际使用中 VPN 网关很少用于多账号网络互通,多用于本地数据中心与 VPC 互通以构建混合云。• CEN 专线连接在网络质量、安全性和传输速度等方面都优于 VPN,但是 CEN 在跨账号连接时需要配置跨账号授权、路由等,存在一定的配置成本;跨 Region 通信时需要购买带宽,存在一定的费用成本;每个 CEN 实例在每个 Region 可加载的网络实例数量有限。 由此可见,VPN 和 CEN 都能解决多账号网络互通问题,但是不一定适合所有的场景,还有其他的方案吗? ResourceSharing 介绍 不同于 VPN 和 CEN,资源共享服务(ResourceSharing)通过在账号间共享 VSwitch 来实现多账号网络互通。如下图所示:企业账号 A、B、C、D 加入 ResourceDirectory(资源目录)后,资源所有者账号 A 把虚拟交换机共享给账号 B、C、D,这样账号 A、B、C、D 都能使用该虚拟交换机,并在该交换机上挂载 ECS/RDS/SLB 等资源,以此来实现不同账号的资源共享同一个子网。 图3 相对于 CEN 和 VPN,ResourceSharing 极大地简化了配置,在网络规模较复杂的场景下尤为明显。 基于 ResourceSharing 的网络架构 如下图所示为基于 ResourceSharing 的网络架构:账号 1 所在的 VPC 使用两个 VSwitch 作为多可用区以实现同城双活,用于部署前端服务;再共享三个 VSwitch 给账号 2 和账号 3 用于部署后端服务:“Shared VSwitch For AZ1 ECS” 用于挂截账号 2 和账号 3 在 AZ1 的 ECS 资源,“Shared VSwitch For AZ2 ECS” 用于挂截账号 2 和账号 3 在 AZ2 的 ECS 资源,“Shared VSwitch For SLB” 用于挂截账号 2 和账号 3 的 SLB 资源;这样基于资源共享的方式,前端服务与后端服务均在同一个 VPC 下,所有服务天然支持网络互通。 图4 由于每个账号仍然独立管控自己的资源,所以服务之间既实现了多账号间网络互通,又保证了相关资源在账号间的隔离,此外,相对于 CEN 和 VPN,ResourceSharing 有一定的优势:• 整个体系在一个 VPC 中,因此不需要网关、路由、IPSEC、跨账号授权等相关配置,极大地简化了工作量。• 服务在 VPC 内部通信,不依赖公网带宽,减少了网络延时和丢包率带来的风险。• ResourceSharing 是完全免费的,能为用户节省不少成本。 总结 ResourceSharing 有众多优势,是否能取代 VPN 和 CEN 满足所有的应用场景呢?• 由于 VPC 是地域级别的资源,因此 ResourceSharing 是不能跨 Region 共享 VSwitch 的,而 CEN 则没有这个限制,所以跨 Region 间 VPC 通信时通常选择 CEN 的方式。如下图所示 Region A 和 Region B 的 VPC 通过 CEN 互通。• 当用户需要将本地数据中心与 VPC 互通以构建混合云时,ResourceSharing 显然无法满足需求。如下图所示通过 VPN 的方式将本地数据中心与安全登陆 VPC 快速连接起来。• 当企业对安全有更高要求时,往往需要通过 VPC 将网络划分成多个安全域,ResourceSharing 由于共享 VSwitch 所在的实例都在同一个 VPC,无法满足需求。如下图所示:根据安全级别的不同,将整个网络分隔成多个 VPC,通过 CEN 实现不同安全域 VPC 的网络互通,利用 ResourceSharing 实现多账号同安全域 VPC 的网络互通。 图5 VPN 网关、CEN 和 ResourceSharing 分别适用于不同的场景,如上图所示为集团化的大型企业,网络架构较为复杂,同时用到了三种方案,用户在实际使用时,需要根据自己的需求和网络规模选择最合适的方案。

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

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文件系统,支持十年生命周期更新。

用户登录
用户注册