后场思库OpenSkill开放注册

程序猿的世界很简单也很单纯,但是他们是一群有思想的人,世界那么大,在代码的海洋不断探索。后场思库OpenSkill是一个互联网技术极客平台,希望在这个平台汇集一批有想法有思想的程序员、设计师、测试、运维、区块链、极客、和未知技术探索者,大家来自天南地北,有机会...
继续阅读 »

程序猿的世界很简单也很单纯,但是他们是一群有思想的人,世界那么大,在代码的海洋不断探索。

后场思库OpenSkill是一个互联网技术极客平台,希望在这个平台汇集一批有想法有思想的程序员、设计师、测试、运维、区块链、极客、和未知技术探索者,大家来自天南地北,有机会汇集一处,就是缘分,多一个朋友多一条路。

工作不是人生的全部,生活和家庭才是, 搬砖累了,工作累了,希望这里会成为你的思考栖息之地。

祝福有思想的你,交个朋友......

  请微信扫描如下二维码,对话框回复 社区注册

   539c34c66aeb9979725bfe2b3134a632.png

OpenSkill.cn内容发布原则:

1. 非常欢迎分享程序员故事、有趣味、开阔视野、创新思路的原创文章,不管是锦衣玉食还是馒头榨菜,有趣有料,宁缺毋滥。尊重用户,尊重用户的时间和注意力;

2. 发布的翻译文章要简洁清晰易懂,并附上原文链接;

3. 分享阅读的文章,请附上原文链接;

4. 支持原创文章,不允许未经授权转载别人的文章;

5. 做自己;

6. 不允许发布灌水充数的文章,毫无价值的文章;

7. 不允许发布涉及钱财的文章,比如赞助、捐助、乞讨、众筹、抽奖、贷款等;

8. 不允许发布纯广告营销、擦边球、灰黑违内容;

9. 不允许标题党;

10. 请务必遵守服务条款,违者永禁。

收起阅读 »

MySQL8和PostgreSQL10功能对比

现在MySQL 8和PostgreSQL 10已经发布,现在是重新审视两个主要的开源关系数据库如何相互竞争的好时机。 在这些版本之前,一般的看法是,虽然Postgres在功能集及血统方面更胜一筹,但MySQL在大规模并发读/写操作方面进行了更多的大规模测试。 ...
继续阅读 »

现在MySQL 8PostgreSQL 10已经发布,现在是重新审视两个主要的开源关系数据库如何相互竞争的好时机。


在这些版本之前,一般的看法是,虽然Postgres在功能集及血统方面更胜一筹,但MySQL在大规模并发读/写操作方面进行了更多的大规模测试。


但是随着最新版本的发布,两者之间的差距已大大缩小。


功能对比

下面看一下通常我们认为比较时髦的功能。






































特征 MySQL8 PostgreSQL10
查询和分析
通用表达式(CTEs) ✔ New
视窗功能 ✔ New
数据类型
支持JSON ✔ Improved
GIS / SRS ✔ Improved
全文搜索
扩展性
逻辑复制 ✔ New
半同步复制 ✔ New
声明式分区 ✔ New

过去常常说MySQL最适合在线交易,而PostgreSQL最适合分析过程,但是现在不再是如此局面。


通用表达式(CTEs)和窗口函数一直是多数人选择PostgreSQL的主要原因。但是现在,在同一个表中employees引用对表进行递归遍历boss_id,或者在排序结果中找到中间值(或50%百分位数),在MySQL上不再是问题。


PostgreSQL上的复制缺乏配置灵活性,这是Uber转向MySQL的原因。但是现在有了逻辑复制,可以通过使用更新版本的Postgres创建副本并切换到该副本来实现零停机时间升级。截断大型时序事件表中的陈旧分区也容易得多。


在功能方面,两个数据库现在彼此相同。


二者有什么区别?

现在有一个问题就是,我们到底是选择MySQL还是PostgreSQL,那选择的原因又是什么?


生态系统就是这些因素之一。MySQL拥有一个强大的生态系统,其中包含MariaDB,Percona,Galera等变体,以及InnoDB以外的其他存储引擎,但它们也可能令人不知所措。Postgres的高端选项有限,但是随着最新版本引入的新功能,这种情况将会改变。


治理是另一个因素。每个人都在担心甲骨文(或最初为SUN)收购MySQL时,他们会毁了该产品,但过去十年来情况并非如此。实际上,收购后发展加速。Postgres在工作治理和协作社区方面拥有悠久的历史。


体系结构的基本原理不会经常更改,但是值得值得我们回顾。





























特征 MySQL8 PostgreSQL10
架构 单进程 多进程
并发 多线程 fork(2)
表结构 聚合索引 Heap(堆)
页面压缩 透明 TOAST
更新 就地/回滚Segments 仅追加/ Hot
垃圾回收 清除线程 自动回收进程
Transaction Log REDO Log (WAL) WAL
Replication Log Separate (Binlog) WAL

进程对比线程

Postgres fork一个子进程来建立连接时,每个连接最多需要10 MB的空间。与MySQL的“每次连接线程”模型相比,内存压力更大,后者在64位平台上,线程的默认堆栈大小为 256KB。(当然,线程局部排序缓冲区等可以使此开销的重要性降低,即使可以忽略不计,但仍然如此。)


即使写时复制会与父进程一起保存一些共享的,不变的内存状态,但是当您有1000个以上的并发连接时,作为基于进程的体系结构的基本开销会增加负担,并且它可能是最重要的开销之一能力计划的因素。


也就是说,如果您在30台服务器上运行Rails应用程序,其中每台服务器具有16个CPU内核和32个Unicorn worker,则您有960个连接。在所有应用程序中,可能只有不到0.1%会达到这个规模,但这是需要牢记的。


聚合索引对比堆(Heap)表

聚合索引是其中行被直接嵌入主键的B树结构内的表结构。(非聚和)堆(Heap)是规则表结构,其中填充了与索引分开的数据行。


使用聚合索引时,当您通过主键查找记录时,单个I / O将检索整行,而非聚集索引始终通过遵循引用至少需要两个I / O。由于外键引用和联接将触发主键查找,因此影响可能很大,这将占查询的绝大多数。


聚合索引的理论缺点是,在使用次级索引进行查询时,遍历树节点的次数是您首先遍历次级索引,然后遍历聚合索引(也是一棵树)的两倍。


但是,考虑到现代惯例,将自动递增的整数作为主键[1](称为代理键),几乎总是希望拥有聚合索引。如果您要执行很多操作ORDER BY id来检索最新(或最旧)的N条记录,那就更是如此,我认为这适用于大多数记录。


Postgres不支持聚和索引,而MySQL(InnoDB)不支持堆(Heap)。但是,无论哪种方式,如果您有大量内存,则差异应该很小。


页面结构和压缩

Postgres和MySQL都具有基于页面的物理存储(8KB和16KB)。


PostgreSQL物理存储简介

页面结构看起来像上图所示。它包含一些标题,我们将在这里不进行介绍,但是它们包含有关页面的元数据。标头后面的项目是一个数组标识符,由(offset, length)指向元组或数据行的对组成。请记住,在Postgres中,可以通过这种方式将同一记录的多个版本存储在同一页面中。

MySQL的表空间结构与Oracle的表空间结构相似,它具有段,范围,页和行的多个层次结构层。


它还为UNDO提供了一个单独的部分,称为“回退部分”。与Postgres不同,MySQL将在同一区域保留同一记录的多个版本。


在两个数据库上,一行必须适合一个页面,这意味着一行必须小于8KB。(MySQL的页面中必须至少包含2行,巧合的是16KB / 2 = 8KB)


那么当列中有一个大的JSON对象时会发生什么?

Postgres使用TOAST(专用的影子表存储)。当且仅当选择行和列时,才会拉出大对象。换句话说,大量的黑盒子不会污染您宝贵的缓存。它还支持对TOASTed对象的压缩。


由于高端SSD存储供应商Fusion-io的贡献,MySQL具有称为“ 透明页面压缩”的更高级功能。它是专门为与SSD配合使用而设计的,固态硬盘的写入量与设备的寿命直接相关。


MySQL上的压缩不仅适用于页面外的大对象,而且适用于所有页面。它是通过在稀疏文件中使用打孔来实现的,稀疏文件ext4btrfs等现代文件系统支持。


有关更多详细信息,请参阅:通过FusionIO上的新MariaDB页面压缩显着提高性能


更新的开销

UPDATE是经常遗漏但对性能有重大影响并且可能是最具争议的主题的另一个功能。


这也是Uber放弃Postgres的另一个原因,这激起了许多Postgres拥护者的反驳。


两者都是MVCC数据库,可保留多个版本的数据以进行隔离)。


为此,Postgres将旧数据保留在堆中直到VACUUMed,而MySQL将旧数据移动到称为回滚段的单独区域。


在Postgres上,当您尝试更新时,必须复制整行以及指向该行的索引条目。部分原因是Postgres不支持聚集索引,因此从索引引用的行的物理位置不会被逻辑键抽象出来。


为了解决此问题,Postgres使用仅堆元组(HOT)尽可能不更新索引。但是,如果更新足够频繁(或者如果一个元组很大),则元组的历史记录很容易从8KB的页面大小中流出,跨越多个页面并限制了功能的有效性。修剪和/或碎片整理的时间取决于试探法。此外,将fillfactor设置为小于100会降低空间效率—这是在表创建时就不必担心的艰难折衷。


这个限制甚至更深了。由于索引元组没有有关事务的任何信息,因此直到9.2 以前一直不可能支持仅索引扫描。它是所有主要数据库(包括MySQL,Oracle,IBM DB2和Microsoft SQL Server)支持的最古老,最重要的优化方法之一。但是即使使用最新版本,当有大量的UPDATE设置Visibility Map中的脏位时,Postgres也不能完全支持仅索引扫描,而在不需要时经常选择Seq扫描。


在MySQL上,更新发生在原地,旧行数据存放在称为回滚段的单独区域中。结果是您不需要VACUUM,提交非常快,而回滚相对较慢,这对于大多数用例来说是一个较好的折衷方案。


它也足够聪明,可以尽快清除历史记录。如果将事务的隔离级别设置为READ-COMMITTED或更低,则在语句完成时将清除历史记录。


交易历史记录的大小不会影响主页。碎片是没有问题的。因此,MySQL的整体性能更好,更可预测。


垃圾回收

Postgres上的VACUUM非常昂贵,因为它可以在主堆区域中工作,从而造成直接的资源争用。感觉就像编程语言中的垃圾回收一样-它会妨碍您并让您随意暂停。


为具有数十亿条记录的表配置自动清空仍然是一个挑战。


对MySQL的清除也可能很繁重,但是由于它在单独的回滚段中使用专用线程运行,因此不会以任何方式对读取并发产生不利影响。即使使用默认设置,膨胀的回滚段也不太可能使您减速。


一个拥有数十亿条记录的繁忙表不会导致MySQL的历史记录膨胀,并且诸如存储文件大小和查询性能之类的事情几乎是可以预测和稳定的。


日志和复制

Postgres有一个唯一的交易历史事实来源,称为Write Ahead Log(WAL)。它也用于复制,称为逻辑复制的新功能可以将二进制内容实时解码为更易消化的逻辑语句,从而可以对数据进行精细控制。


MySQL维护两个单独的日志:1. 用于崩溃恢复的InnoDB特定重做日志,以及2. 用于复制和增量备份的二进制日志


与Oracle一样,InnoDB上的重做日志是免维护的循环缓冲区,不会随着时间的推移而增长,只能在启动时以固定大小创建。这种设计可确保在物理设备上保留连续的连续区域,从而提高性能。重做日志越大,性能越好,但要从崩溃中恢复时间。


在Postgres中添加了新的复制功能后,我称之为平局。


TL和DR

令人惊讶的是,事实证明,普遍的看法仍然成立。MySQL最适合在线交易,而PostgreSQL最适合仅追加分析过程,例如数据仓库。[2]


正如我们在本文中看到的,Postgres的绝大多数复杂性源于其仅附加的,过度冗余的堆体系结构。


Postgres的未来版本可能需要对其存储引擎进行重大改进。您不必完全相信我的话- 官方Wiki上已经讨论了它,这表明是时候从InnoDB那里获取一些好主意了。


一次又一次地说MySQL正在追赶Postgres,但是这次,潮流已经改变了。


  1. 顺便说一句,UUID作为主键是一个可怕的想法-密码随机性是完全设计用来杀死参考位置的,因此会降低性能。↩︎
  2. 当我说Postgres非常适合分析时,我是说真的。如果您不了解TimescaleDB,它是PostgreSQL之上的包装器,可让您每秒插入100万条记录,每服务器100+十亿行。疯狂的事情。难怪亚马逊为什么选择PostgreSQL作为Redshift的基础

英文原文: http://suo.im/6kMihv


收起阅读 »

Linux文件的三个时间属性

时间属性介绍Linux下一个文件通过stat命令可以查看到这个文件时间方面的属性,具体信息如下: # stat tengine-2.0.0-23tf4566.tar.gz File: 'tengine-2.0.0-23tf4566.tar.gz' Si...
继续阅读 »

时间属性介绍

Linux下一个文件通过stat命令可以查看到这个文件时间方面的属性,具体信息如下:


# stat tengine-2.0.0-23tf4566.tar.gz
File: 'tengine-2.0.0-23tf4566.tar.gz'
Size: 35995224 Blocks: 70304 IO Block: 4096 regular file
Device: 802h/2050d Inode: 201842670 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 501/ UNKNOWN) Gid: ( 20/ games)
Access: 2020-07-30 14:07:46.617759798 +0000
Modify: 2020-07-30 12:57:35.000000000 +0000
Change: 2020-10-16 06:20:13.535869875 +0000
Birth: -

如上所示,可以看出来分别有Access Modify Change 三个关于时间的属性。


此三个属性初始时间记录都是文件被创建的时间:


  • Access 指最后一次读取的时间(访问)
  • Modify 指最后一次修改数据的时间(修改)
  • Change 指最后一次修改元数据的时间(改变)

Access的意思是访问:


在终端上用cat、more 、less、grep、sed、 cp 、file 一个文件时,此文件的Access的时间记录都会被更新(空文件例外),纯粹的access是不会影响modify和change,但会受到modify行为的影响。


ls -lu看到的文件时间是最近一次access的时间。对于目录而言,只是进入目录的话不会改变它的access时间,但只要用ls查看了此目录的内容(无论在何处),这个目录的access时间就会被更新。


Modify 意思是更改(内容)or 写入:


当更改了一个文件的内容的时候,此文件的modify的时间记录会被更新。用ls -l看到的文件时间是最近一次modify的时间。modify的行为是三个行为中最有影响力的行为,它发生以后,会使文件的access记录与change记录也同时得到更新, 对于目录亦是如此。


Change 改变(状态或属性):
对一个文件或者目录作mv、chown、chgrp操作后,它的Change时间记录被更新,change时间会受到modify行为的影响。ls -lc看到的文件时间是最近一次change的时间。


# stat test.txt 
File: ‘test.txt’
Size: 10 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 201843904 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-10-16 06:44:21.925299516 +0000
Modify: 2020-10-16 06:44:21.925299516 +0000
Change: 2020-10-16 06:44:21.925299516 +0000
Birth: -

# cat test.txt
lucky boy

# stat test.txt
File: ‘test.txt’
Size: 10 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 201843904 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-10-16 06:44:43.911988787 +0000
Modify: 2020-10-16 06:44:21.925299516 +0000
Change: 2020-10-16 06:44:21.925299516 +0000
Birth: -

如上用cat命令将文件test.txt的内容输出到终端( 执行 cat test.txt), 那么文件test.txt只有的Access被刷新。


# date >> test.txt 
# stat test.txt
File: ‘test.txt’
Size: 39 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 201843904 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-10-16 06:44:43.911988787 +0000
Modify: 2020-10-16 06:46:56.760155796 +0000
Change: 2020-10-16 06:46:56.760155796 +0000
Birth: -

如上把当前的时间追加到test.txt(执行 date >> test.txt) , 那么test.txt的ModifyChange都被刷新。


# chmod 777 test.txt 
# stat test.txt
File: ‘test.txt’
Size: 39 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 201843904 Links: 1
Access: (0777/-rwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-10-16 06:44:43.911988787 +0000
Modify: 2020-10-16 06:46:56.760155796 +0000
Change: 2020-10-16 06:48:45.676571600 +0000
Birth: -

如上把test.txt的权限改为777(执行 chmod 777 test.txt) , 那么只有test.txtChange被刷新。


假如我们用vi命令把文件test.txt打开, 然后保存退出,那么test.txtAccess、ModifyChange都会被刷新。


同时我们也可以使用命令touch更新test.txt的Access和Modify时间:


touch -d 1999-01-01 test.txt    // 将test.txt的Access和Modify时间改为1999-01-01
touch -a test.txt // 只将test.txt的Access时间改为当前系统时间
touch -m test.txt // 只将test.txt的Modify时间改为当前系统时间

当我们用ls -l test.txt看到的时间就是Modify时间。


按照时间排序文件

# ls -l
-rw-r--r-- 1 501 games 35995224 Jul 30 12:57 tengine-2.0.0-23tf4566.tar.gz
-rw-r--r-- 1 501 games 4321420 Jul 22 14:15 tengine-2.0.0-45axfa54.tar.gz
-rw-r--r-- 1 501 games 33238934 Jul 22 15:20 tengine-2.0.0-64af1234.tar.gz

如上有3个文件,如果按照时间排序呢?


按照修改时间排序:


ls -alt  等价于 ls --sort=time -la

按照创建时间排序:


ls -alc

按访问时间排序:


ls -alu

以上均可使用-r实现逆序排序


ls -alrt # 按修改时间排序
ls --sort=time -lra # 等价于> ls -alrt
ls -alrc # 按创建时间排序
ls -alru # 按访问时间排序

不管你是根据什么排序,加上-r 就会反序。

收起阅读 »

Kafka Topic创建三步曲

通常在生产环境新增业务主题,我们都需要提前预测到,然后做好充分的准备,本文将介绍在生产环境中创建Topic时需要考虑的所有参数。 首先创建新Topic的时候,我们需要设置合理的分区数和副本数,不合理的设置将会给系统的性能和可靠性带来影响。 创建一个Topic...
继续阅读 »

Kafka Topic Consumer

通常在生产环境新增业务主题,我们都需要提前预测到,然后做好充分的准备,本文将介绍在生产环境中创建Topic时需要考虑的所有参数。


首先创建新Topic的时候,我们需要设置合理的分区数和副本数,不合理的设置将会给系统的性能和可靠性带来影响。


创建一个Topic

kafka/bin/kafka-topics.sh --create \
--zookeeper localhost:2181 \
--replication-factor 2 \
--partitions 3 \
--topic unique-topic-name

分区(Partitions)

Kafka主题分为多个分区,其中包含以不变顺序排列的消息。分区中的每个消息均通过其唯一偏移量进行分配和标识。


分区使我们可以在多个Broker之间分配主题数据,从而平衡Broker之间的负载。每个分区只能由一个Consumer Group使用,因此,服务的并行性受Topic拥有的分区数约束。


分区数受两个主要因素的影响,即消息数和每条消息的平均大小。如果交易量很大,您将需要使用代理数量作为乘法倍数,以允许在所有使用者上共享负载,并避免创建热分区,该分区会对特定代理造成高负载。我们的目标是使分区吞吐量达到1MB/s。


设置分区数:


--partitions [number]

副本(Replicas)

Kafka Topic Producer writes

如果leader分区发生故障并且需要跟随者(follower)副本替换它并成为领导者(leader),则Kafka可以选择复制Topic分区。在配置Topic时,请记住,分区是为实现快速读写速度,可伸缩性和分发大量数据而设计的。


另一方面,复制因子(RF)旨在确保指定的容错目标。副本不会直接影响性能,因为在任何给定时间,只有一个(leader)领导者分区负责通过Broker服务器处理生产者和使用者请求。


在决定复制因子时的另一个考虑因素是,为了满足生产容量会话,需要考虑服务需要的消费者数量。


设置复制因子(RF):
如果你的Topic承载的是关键业务,推荐你设置复制因子为3,其他的设置为2就够了。

--replication-factor [number]

Tips:  但这里需要注意一点的是, RF <= Broker Number



保留(Retention)

将消息保留在Topic中的时间或最大Topic大小。根据你的用例确定。默认情况下,保留期限为7天,但这是可配置的。


设置Retention:


--config retention.ms=[number]

压缩(Compaction)

为了释放空间并清理不需要的记录,Kafka压缩可以根据记录的日期和大小删除记录。它还可以删除具有相同键的每个记录,同时保留该记录的最新版本。基于键的压缩对于控制Topic的大小非常有用,其中只有最新的记录版本才是重要的。


启用压缩:


log.cleanup.policy=compact

分享阅读原文: http://suo.im/5W8p1p

收起阅读 »

Python下判断文件是否为二进制文件的三种方法

常用的有两种方法判断文件是否为二进制文件,最准确的就是把这两种方法结合起来更加准确点. 方法1利用codecs模块它首先检查文件是否以BOM开始,如果不在初始8192字节内查找零字节: import codecs file_path = "/home/ubu...
继续阅读 »

常用的有两种方法判断文件是否为二进制文件,最准确的就是把这两种方法结合起来更加准确点.


方法1利用codecs模块

它首先检查文件是否以BOM开始,如果不在初始8192字节内查找零字节:


import codecs

file_path = "/home/ubuntu/zgd/ztest/_gs418_510txp_v6.6.2.7.stk.extracted/test"

#: BOMs to indicate that a file is a text file even if it contains zero bytes.
_TEXT_BOMS = (
codecs.BOM_UTF16_BE,
codecs.BOM_UTF16_LE,
codecs.BOM_UTF32_BE,
codecs.BOM_UTF32_LE,
codecs.BOM_UTF8,
)


def is_binary_file(file_path):
with open(file_path, 'rb') as file:
initial_bytes = file.read(8192)
file.close()
return not any(initial_bytes.startswith(bom) for bom in _TEXT_BOMS) and b'\0' in initial_bytes

if __name__ == "__main__":
print is_binary_file(file_path)

上面is_binary_file()函数也可以改成下面的方式:


def is_binary_file(file_path):
with open(file_path, 'rb') as file:
initial_bytes = file.read(8192)
file.close()
for bom in _TEXT_BOMS:
if initial_bytes.startswith(bom):
continue
else:
if b'\0' in initial_bytes:
return True
return False


方法2利用magic模块

安装模块: pip install python-magic


def getFileType(ff):
mime_kw = 'x-executable|x-sharedlib|octet-stream|x-object' ###可执行文件、链接库、动态流、对象
try:
magic_mime = magic.from_file(ff, mime=True)
magic_hit = re.search(mime_kw, magic_mime, re.I)
if magic_hit:
return True
else:
return False
except Exception, e:
print e.message

最好的方法是对两种类型同时进行处理:


# -*- coding:utf-8 -*-
# @Author:zgd
# @time:2019/6/21
# @File:operateSystem.py

import magic
import re
import codecs

def is_binary_file_1(ff):
'''
根据text文件数据类型判断是否是二进制文件
:param ff: 文件名(含路径)
:return: True或False,返回是否是二进制文件
'''

TEXT_BOMS = (
codecs.BOM_UTF16_BE,
codecs.BOM_UTF16_LE,
codecs.BOM_UTF32_BE,
codecs.BOM_UTF32_LE,
codecs.BOM_UTF8,
)
with open(file_path, 'rb') as file:
CHUNKSIZE = 8192
initial_bytes = file.read(CHUNKSIZE)
file.close()
#: BOMs to indicate that a file is a text file even if it contains zero bytes.
return not any(initial_bytes.startswith(bom) for bom in TEXT_BOMS) and b'\0' in initial_bytes


def is_binwary_file_2(ff):
'''
根据magic文件的魔术判断是否是二进制文件
:param ff: 文件名(含路径)
:return: True或False,返回是否是二进制文件
'''

mime_kw = 'x-executable|x-sharedlib|octet-stream|x-object' ###可执行文件、链接库、动态流、对象
try:
magic_mime = magic.from_file(ff, mime=True)
magic_hit = re.search(mime_kw, magic_mime, re.I)
if magic_hit:
return True
else:
return False
except Exception, e:
return False


if __name__ == "__main__":
file_path = "/home/ubuntu/zgd/ztest/_gs418_510txp_v6.6.2.7.stk.extracted/D0"
print is_binary_file_1(file_path)
print is_binwary_file_2(file_path)
print any((is_binary_file_1(file_path), is_binwary_file_2(file_path)))


方法3判断是否有ELF头

根据文件中是否有ELF头进行判断文件是否为二进制文件


# 判断文件是否是elf文件
def is_ELFfile(filepath):
if not os.path.exists(filepath):
logger.info('file path {} doesnot exits'.format(filepath))
return False
# 文件可能被损坏,捕捉异常
try:
FileStates = os.stat(filepath)
FileMode = FileStates[stat.ST_MODE]
if not stat.S_ISREG(FileMode) or stat.S_ISLNK(FileMode): # 如果文件既不是普通文件也不是链接文件
return False
with open(filepath, 'rb') as f:
header = (bytearray(f.read(4))[1:4]).decode(encoding="utf-8")
# logger.info("header is {}".format(header))
if header in ["ELF"]:
# print header
return True
except UnicodeDecodeError as e:
# logger.info("is_ELFfile UnicodeDecodeError {}".format(filepath))
# logger.info(str(e))
pass

return False
收起阅读 »

sed常用替换小技巧记录

1. 去掉行首空格 sed 's/^[ \t]*//g'2. 去掉行末空格 sed 's/[ \t]*$//g'3. 去掉所有空格 sed s/[[:space:]]//g4. 替换符号 sed "s/^\(.*\)$/'\1'/" sed "s/^\(.*...
继续阅读 »
1. 去掉行首空格
sed 's/^[ \t]*//g'
2. 去掉行末空格
sed 's/[ \t]*$//g'
3. 去掉所有空格
sed s/[[:space:]]//g
4. 替换符号
sed "s/^\(.*\)$/'\1'/" 
sed "s/^\(.*\)$/aa =>\1/"
收起阅读 »

一些常见错误技术问题汇总

Q: 启动apache报错 [warn] module php5_module is already loaded, skipping 一般出现这种问题有两种情况: 1.在apache安装目录conf下httpd.conf里可能重复了一行LoadModul...
继续阅读 »


Q: 启动apache报错 [warn] module php5_module is already loaded, skipping


一般出现这种问题有两种情况:
1.在apache安装目录conf下httpd.conf里可能重复了一行LoadModule php5_module modules/libphp5.so,删除重复的行就行。
 
2.或者在其他的conf文件中加载load了,如下yum安装的httpd,conf.d/php.conf里

LoadModule php5_module modules/libphp5.so


Q: centos 6.2 更新报错解决 yum you could try using skip broken to work around the problem


 
# yum update
Loaded plugins: aliases, changelog, downloadonly, kabi, presto, refresh-
: packagekit, security, tmprepo, verify, versionlock
Loading support for Red Hat kernel ABI
adobe-linux-x86_64 | 951 B 00:00
google-chrome | 951 B 00:00 ...
sl | 3.2 kB 00:00
sl-security | 1.9 kB 00:00
Setting up Update Process
Resolving Dependencies
--> Running transaction check
---> Package python-qpid.noarch 0:0.12-1.el6 will be updated
---> Package python-qpid.noarch 0:0.14-11.el6_3 will be an update
---> Package python-qpid-qmf.x86_64 0:0.12-6.el6 will be updated
---> Package python-qpid-qmf.x86_64 0:0.14-14.el6_3 will be an update
---> Package qpid-cpp-client.x86_64 0:0.12-6.el6 will be updated
--> Processing Dependency: libqpidclient.so.5()(64bit) for package: matahari-agent-lib-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidclient.so.5()(64bit) for package: matahari-network-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidclient.so.5()(64bit) for package: matahari-sysconfig-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidclient.so.5()(64bit) for package: matahari-service-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidclient.so.5()(64bit) for package: matahari-host-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidcommon.so.5()(64bit) for package: matahari-network-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidcommon.so.5()(64bit) for package: matahari-host-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidcommon.so.5()(64bit) for package: matahari-sysconfig-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidcommon.so.5()(64bit) for package: libvirt-qmf-0.3.0-4.el6.x86_64
--> Processing Dependency: libqpidcommon.so.5()(64bit) for package: matahari-agent-lib-0.4.4-11.el6.x86_64
--> Processing Dependency: libqpidcommon.so.5()(64bit) for package: matahari-service-0.4.4-11.el6.x86_64
---> Package qpid-cpp-client.x86_64 0:0.14-22.el6_3 will be an update
---> Package qpid-cpp-client-ssl.x86_64 0:0.12-6.el6 will be updated
---> Package qpid-cpp-client-ssl.x86_64 0:0.14-22.el6_3 will be an update
---> Package qpid-cpp-server.x86_64 0:0.12-6.el6 will be updated
---> Package qpid-cpp-server.x86_64 0:0.14-22.el6_3 will be an update
---> Package qpid-cpp-server-ssl.x86_64 0:0.12-6.el6 will be updated
---> Package qpid-cpp-server-ssl.x86_64 0:0.14-22.el6_3 will be an update
---> Package qpid-qmf.x86_64 0:0.12-6.el6 will be updated
---> Package qpid-qmf.x86_64 0:0.14-14.el6_3 will be an update
---> Package qpid-tools.noarch 0:0.12-2.el6 will be updated
---> Package qpid-tools.noarch 0:0.14-6.el6_3 will be an update
---> Package ruby-qpid-qmf.x86_64 0:0.12-6.el6 will be updated
---> Package ruby-qpid-qmf.x86_64 0:0.14-14.el6_3 will be an update
--> Finished Dependency Resolution
Error: Package: matahari-host-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidclient.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidclient.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-sysconfig-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidclient.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidclient.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-service-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidcommon.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidcommon.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-network-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidclient.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidclient.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-sysconfig-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidcommon.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidcommon.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-host-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidcommon.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidcommon.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: libvirt-qmf-0.3.0-4.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidcommon.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidcommon.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-agent-lib-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidcommon.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidcommon.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-network-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidcommon.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidcommon.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-agent-lib-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidclient.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidclient.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
Error: Package: matahari-service-0.4.4-11.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
Requires: libqpidclient.so.5()(64bit)
Removing: qpid-cpp-client-0.12-6.el6.x86_64 (@anaconda-ScientificLinux-201202061444.x86_64)
libqpidclient.so.5()(64bit)
Updated By: qpid-cpp-client-0.14-22.el6_3.x86_64 (sl-security)
Not found
You could try using --skip-broken to work around the problem
** Found 1 pre-existing rpmdb problem(s), 'yum check' output follows:
libvpx-1.0.0-1.el6.x86_64 is a duplicate with libvpx-0.9.0-8.el6_0.x86_64
上述更新错误,解决方法如下:
yum remove matahari*执行完后,然后执行yun update 更新,这样应该就可以了。


Q: Cannot load /…/libphp5.so into server: /…/libphp5.so: undefined symbol: _efree


此错误是由于重装php时,没有关闭apache。解决方法:调转到php安装目录,执行“make clean”,然后从新安装php,记得安装之前关闭apache。


Q: apache启动报错(98)Address already in use: make_sock: could not bind to address :80


端口占用情况:
#netstat -lnp|grep 80
#ps 端口号为80的进程
#kill -9 端口号为80的进程(可能进程不止一个)


Q: 从源码安装apache2,遇到错误:cannot install `libaprutil-1.la'


这是由于configure过一次,没有清理干净,需要清理。可以删除掉源码目录,重新解压源码,重新安装,或者make clean. 收起阅读 »

golang静态编译

golang 的编译(不涉及 cgo 编译的前提下)默认使用了静态编译,不依赖任何动态链接库。 这样可以任意部署到各种运行环境,不用担心依赖库的版本问题。只是体积大一点而已,存储时占用了一点磁盘,运行时,多占用了一点内存。早期动态链接库的产生,是因为早期的系统...
继续阅读 »

golang 的编译(不涉及 cgo 编译的前提下)默认使用了静态编译,不依赖任何动态链接库。


这样可以任意部署到各种运行环境,不用担心依赖库的版本问题。只是体积大一点而已,存储时占用了一点磁盘,运行时,多占用了一点内存。早期动态链接库的产生,是因为早期的系统的内存资源十分宝贵,由于内存紧张的问题在早期的系统中显得更加突出,因此人们首先想到的是要解决内存使用效率不高这一问题,于是便提出了动态装入的思想。也就产生了动态链接库。在现在的计算机里,操作系统的硬盘内存更大了,尤其是服务器,32G、64G 的内存都是最基本的。可以不用为了节省几百 KB 或者1M,几 M 的内存而大大费周折了。而 golang 就采用这种做法,可以避免各种 so 动态链接库依赖的问题,这点是非常值得称赞的。


显示指定静态编译方法
在Docker化的今天, 我们经常需要静态编译一个Go程序,以便方便放在Docker容器中。 即使你没有引用其它的第三方包,只是在程序中使用了标准库net,你也会发现你编译后的程序依赖glic,这时候你需要glibc-static库,并且静态连接。

不同的Go版本下静态编译方式还有点不同,在go 1.10下, 下面的方式会尽可能做到静态编译:


CGO_ENABLED=0 go build -a -ldflags '-extldflags "-static"' .
收起阅读 »

告诉你真实的软件开发Bug产生过程

bug
领导:修个房子。程序员:好的,马上开始打地基!领导:你看那隔壁那木房子就没有打地基,不要在小事上浪费时间,一个月水平面上面什么都看不到,你kpi不要了?这是敏捷开发。一层房子修好。领导:我觉得两层楼的视野好,再加一层。程序员:可是我们没有地基,重新打地基要时间...
继续阅读 »

领导:修个房子。

程序员:好的,马上开始打地基!

领导:你看那隔壁那木房子就没有打地基,不要在小事上浪费时间,一个月水平面上面什么都看不到,你kpi不要了?

这是敏捷开发


一层房子修好。

领导:我觉得两层楼的视野好,再加一层。

程序员:可是我们没有地基,重新打地基要时间……

领导:你一楼都修好了,照着再修个一模一样二楼很难?还要很多时间?

这是高速版本迭代


二楼修好。

领导:天天走路累死了,你再修个电梯。

程序员:可是……

领导:没什么可是的,地基不稳?就在房子边上搭个电梯就行了嘛,不稳拿根木棍撑一下,这都不懂?

这是版本优化


电梯修好。

领导:我觉得顶楼再加个游泳池就好了。

程序员:这个结构行业翘楚的房子也不支持呀!

领导:那不正显得我们牛逼么?修快点,夏天要来了。

这是快速功能追加


游泳池修好,看着摇摇欲坠的房子,程序员跑路了,领导找来新人继续。

领导:我觉得游泳池水不够满,你加点的,一楼光线不好你在墙上打个窗户。

新人:好的,没问题领导,马上加一桶水,马上砸墙

这是打补丁


房子塌了,电梯倒了,游泳池垮了……

领导:真是个废物,就让他加桶水,居然能把房子弄倒了,你说这是多没用?

新人:我真的就加了桶水,我怎么知道为什么。

这是软件莫名崩溃

来源: 知乎
作者:哒柏
链接:http://suo.im/6kaAEi

收起阅读 »

AIOps根因分析最佳实践

随着基础架构和软件环境变得越来越复杂,检测性能或可用性问题的根因变得越来越具有挑战性。幸运的是,迎接挑战的是一类新的工具和一种新的策略:AIOps。什么是根因分析?在IT中,根因分析是确定硬件或软件问题的根本问题原因是什么的过程。根因分析很重要,因为在许多情况...
继续阅读 »

随着基础架构和软件环境变得越来越复杂,检测性能或可用性问题的根因变得越来越具有挑战性。幸运的是,迎接挑战的是一类新的工具和一种新的策略:AIOps。

什么是根因分析?
在IT中,根因分析是确定硬件或软件问题的根本问题原因是什么的过程。

根因分析很重要,因为在许多情况下,有多个可能的问题原因,而且从问题本身来看,原因并不明显。例如,如果应用程序开始响应缓慢,则仅凭这些信息就很难知道问题的原因是否是应用程序本身编写的糟糕的代码,还是托管应用程序的操作系统存在的问题,还是文件系统存在问题。应用程序正在使用,应用程序所依赖的网络或存储基础结构出现问题或其他原因。也可能有多个潜在问题在起作用。

为什么当前根因分析尤其重要
从前,根因分析相对简单,因为IT团队需要管理的硬件和软件层较少。物理基础架构和硬件环境之间也几乎没有抽象。因此,如果监控软件检测到磁盘性能问题,则可以相对确定磁盘本身或用于格式化磁盘的文件系统是根本问题。

但是,今天,我们依赖高度动态的多层软件定义环境。映射这些环境中所有组件之间的关系非常困难,尤其是因为配置不断变化。很难解释在环境的一层中表现出来的问题与其他层之间的关系。

如今,存储性能问题的根因可能不一定是物理磁盘或本地文件系统,还可能是使存储可供远程系统使用的网络或分布式文件系统。也可能是提供存储的虚拟化网络。

充分利用AIOps进行根因分析
部分原因是由于现代环境中根因分析的困难, AIOps变得如此重要。通过使用机器学习自动映射和解释复杂的环境和因果关系,AIOps可以帮助IT团队比仅依靠手动分析更快地找到性能或可用性问题的根源。简单地使用AIOps工具将大大提高您的根本原因分析能力。

就是说,您可以采取一些步骤来确保充分利用AIOps辅助的根本原因分析。它们包括以下内容。

1. 记住,配置快速变更,根因也会随之变更

在瞬息万变的现代环境中进行根因分析的棘手事情之一是,一次构成根本问题的原因可能在下一时刻改变。应用程序性能缓慢的根本原因可能是网络拥塞,但随着网络流量模式和存储系统负载的变化,下一阶段将变为IO瓶颈。

AIOps工具可以帮助解决这些变化,但是对于人类工程师而言,重要的是要记住根因是可以改变的。不要认为核心问题是一成不变的。

2. 考虑自动响应

AIOps的另一个关键功能是它使软件工具可以采取自动措施来解决问题。尽管并不是在每种情况下都自动响应是正确的解决方案(例如,您可能希望让人工工程师在进行重大变更之前先进行审查),但对于更简单的问题的自动响应可以有效地帮助确保您不仅识别根因可以快速解决,也可以在最终给用户造成严重问题之前解决它们。

3. 不要假设只有一个根因

如上所述,软件或硬件问题的原因可能是多个问题。停止响应的应用程序可能会这样做,因为代码编写得不好,无法使应用程序从意外的网络错误中恢复;在这种情况下,应用程序代码和网络问题都是此问题的根因。

这里的关键要点是,一方面,在执行根因分析时,您应努力将辅助问题与根因区分开,但您不应排除可能存在两个或多个核心潜在问题的可能性。

4. 力求与环境无关的根本原因分析

理想情况下,根因分析工作流程应对任何类型的基础架构或环境均有效。如果您依赖仅支持特定类型的环境或基础架构的监控或分析工具(例如来自特定云供应商的工具或仅针对一种操作系统设计的工具),则不会发生这种情况。

此处的教训是,您应该寻找AIOps工具,这些工具可以协助对任何类型的基础结构进行根本原因分析。

英文原文:http://suo.im/64aCgc

收起阅读 »