PHP中各种Hash算法性能比较

今天做的模块又用到了Hash函数,突然想起Hash函数可能会比较占CPU资源,所以希望使用一种速度最快的摘要函数。但是PHP中的Hash函数很多,MD4、MD5、SHA-1、SHA-256、SHA-384以及SHA-512,都是比较常见的安全领域的HASH应用。于是写了个程序对比了一下PHP支持的各种Hash函数:


<?php define('testtime', 50000); $algos = hash_algos(); foreach($algos as $algo) { $st = microtime(); for($i = 0; $i < testtime; $i++) { hash($algo, microtime().$i); } $et = microtime(); list($ss, $si) = explode(' ', $st); list($es, $ei) = explode(' ', $et); $time[$algo] = $ei + $es - $si - $ss; } asort($time, SORT_NUMERIC); print_r($time); ?>

此程序测试每种hash函数支持的算法,对50000个字符串执行hash计算,然后将耗时按从低到高排序,结果如下:


Array ( [crc32b] => 1.14942403926 [crc32] => 1.15080493481 [adler32] => 1.17250810205 [md4] => 1.21484698894 [md5] => 1.25582505324 [sha256] => 1.31992111638 [ripemd256] => 1.34005199425 [ripemd128] => 1.34174097336 [sha1] => 1.34424093234 [ripemd160] => 1.36161398381 [haval128,3] => 1.37490507759 [haval160,3] => 1.37925811601 [haval192,3] => 1.37971906387 [haval224,3] => 1.38690299403 [haval256,3] => 1.38968507692 [tiger128,3] => 1.40321999939 [tiger192,3] => 1.42025405684 [tiger160,3] => 1.42113689062 [ripemd320] => 1.42461802158 [haval128,4] => 1.4465580045 [haval160,4] => 1.44935391309 [haval192,4] => 1.45606506625 [haval224,4] => 1.4650528846 [tiger128,4] => 1.47951410777 [tiger192,4] => 1.49081709387 [haval256,4] => 1.50713596634 [haval160,5] => 1.51613600436 [haval224,5] => 1.51645894888 [haval192,5] => 1.51678603177 [haval256,5] => 1.51900808377 [tiger160,4] => 1.52507308815 [haval128,5] => 1.53689793875 [whirlpool] => 1.82801189377 [snefru] => 1.85931909387 [gost] => 1.89863007236 [sha384] => 1.95804009064 [sha512] => 1.97130295938 [md2] => 4.99702701607 )

CRC是冗余验证算法,不适合用来做唯一标识符Hash计算,MD4是最快的摘要算法,MD5次之,SHA系列算法居然是SHA-256最快,比SHA-1还快一些。由此得出结论:要把唯一标识符转换成定长字串可以考虑使用MD4,而密码加密则SHA-1或SHA-256更合适。MD5就没有多少使用的必要了,速度比不过MD4,安全性比不过SHA,还是趁早放弃的好。

Continue Reading

MySQL5.0 Archive 存储引擎 (2) – 试用

尝试驾驭Archive存储引擎

截止作者撰写本文的时候,MySQL5.0还仅在Max版本中支持Archive存储引擎。想了解您的MySQL支持何种存储引擎,您可以在MySQL客户端中输入SHOW ENGINES命令。


mysql> show engines;
+------------+---------+----------------------------------------------------------------+
| Engine | Support | Comment |
+------------+---------+----------------------------------------------------------------+
| MyISAM | YES | Default engine as of MySQL 3.23 with great performance |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables |
| HEAP | YES | Alias for MEMORY |
| MERGE | YES | Collection of identical MyISAM tables |
| MRG_MYISAM | YES | Alias for MERGE |
| ISAM | NO | Obsolete storage engine, now replaced by MyISAM |
| MRG_ISAM | NO | Obsolete storage engine, now replaced by MERGE |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys |
| INNOBASE | YES | Alias for INNODB |
| BDB | YES | Supports transactions and page-level locking |
| BERKELEYDB | YES | Alias for BDB |
| NDBCLUSTER | NO | Clustered, fault-tolerant, memory-based tables |
| NDB | NO | Alias for NDBCLUSTER |
| EXAMPLE | NO | Example storage engine |
| ARCHIVE | YES | Archive storage engine |
| CSV | NO | CSV storage engine |
| FEDERATED | YES | Federated MySQL storage engine |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) |
+------------+---------+----------------------------------------------------------------+

为了测试Archive引擎压缩数据的效果,我们先以一个包含10万行数据的表为数据源,创建几种不同数据引擎的表,看看存储引擎的表现。先声明:以下的性能测试均是在一台拥有2GHz奔腾M处理器和1GB内存的Dell笔记本电脑上,运行WindowsXP系统和MySQL 5.0.10 β版。


mysql> create table test_myisam engine=myisam as select * from client_transaction_hist;
Query OK, 112050 rows affected (1.06 sec)
Records: 112050 Duplicates: 0 Warnings: 0

mysql> create table test_innodb engine=innodb as select * from client_transaction_hist;
Query OK, 112050 rows affected (3.72 sec)
Records: 112050 Duplicates: 0 Warnings: 0

mysql> create table test_archive engine=archive as select * from client_transaction_hist;
Query OK, 112050 rows affected (1.92 sec)
Records: 112050 Duplicates: 0 Warnings: 0

mysql> SELECT table_name table_name,
-> engine,
-> ROUND(data_length/1024/1024,2) total_size_mb,
-> table_rows
-> FROM information_schema.tables
-> WHERE table_schema = 'gim' and
-> table_name like 'test%'
-> ORDER BY 3;
+--------------+---------+---------------+------------+
| table_name | engine | total_size_mb | table_rows |
+--------------+---------+---------------+------------+
| test_archive | ARCHIVE | 1.64 | 112050 |
| test_myisam | MyISAM | 6.46 | 112050 |
| test_innodb | InnoDB | 9.52 | 112050 |
+--------------+---------+---------------+------------+

可以看到,Archive表比MyISAM表要小大约75%,比支持事务处理的InnoDB表小大约83%。接下来再让我们将MyISAM表压缩,比较看看:


C:\Program Files\MySQL\MySQL Server 5.0\data\gim>..\..\bin\myisampack test_myisam.MYI
Compressing test_myisam.MYD: (112050 records)
- Calculating statistics
- Compressing file
67.76%

+--------------+---------+---------------+------------+
| table_name | engine | total_size_mb | table_rows |
+--------------+---------+---------------+------------+
| test_archive | ARCHIVE | 1.64 | 112050 |
| test_myisam | MyISAM | 2.08 | 112050 |
| test_innodb | InnoDB | 9.52 | 112050 |
+--------------+---------+---------------+------------+

即便是启用了压缩之后,Archive表依然比MyISAM表小约7%。那么执行INSERT插入的速度呢?前面的例子使用CREATE TABLE … AS SELECT …语句向Archive表中插入数据时,性能表现不如MyISAM表好。但这是数据少的情况,当数据量非常大的时候Archive的插入性能表现会较MyISAM为佳。在接下来的例子里,我们要用一个存储过程插入100万行记录:


mysql> create table insert_test (c1 int, c2 varchar(20)) engine=myisam;
Query OK, 0 rows affected (0.00 sec)

mysql> drop procedure test_insert;
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter //
mysql> create procedure test_insert()
-> begin
-> declare v_ctr tinyint;
-> set v_ctr = 0;
-> while v_ctr <> do
-> insert into insert_test values (1,'testing insert');
-> set v_ctr = v_ctr + 1;
-> end while;
-> end
-> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call test_insert();
Query OK, 1 row affected (33.06 sec)

mysql> truncate table insert_test;
Query OK, 0 rows affected (0.01 sec)

mysql> alter table insert_test engine=archive;
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0

mysql> call test_insert();
Query OK, 1 row affected (21.42 sec)

正如你所看到的,在这个INSERT测试例子中,Archive引擎比MyISAM更快。在某些情况下,使用INSERT DELAYED(延迟写入)选项能让Archive引擎的插入速度更快。启用DELAYED选项时,Archive引擎会使用一个压缩缓冲区来保存插入的数据,这当然也能起到提高性能的作用。还有一种方法是直接对标准MyISAM表执行ALTER TABLE语句转换成Archive表:


mysql> alter table myisam_insert engine=archive;
Query OK, 3000000 rows affected, 0 warning (8.84 sec)
Records: 3000000 Duplicates: 0 Warnings: 0

上面的测试显示,将拥有300万行的MyISAM表转换成Archive表只花了不到9秒的时间,太棒了!

读取性能又如何呢?Archive和其他MySQL存储引擎相比较,有何不同?Archive表的第一个弊端是它不支持索引,所以任何SELECT指令都会扫描整个表。MySQL团队正在测试Archive表的索引支持,可能在更高的版本中会发布。但是到目前为止,唯一能帮助提高SELECT执行速度的就是MySQL查询缓存了。

我们来测试一下三种不同存储引擎的数据表(刚超过10万行)执行完全扫描的性能表现:


mysql> select count(*) from test_myisam where client_id = 50;
+----------+
| count(*) |
+----------+
| 24 |
+----------+
1 row in set (0.25 sec)

mysql> select count(*) from test_innodb where client_id = 50;
+----------+
| count(*) |
+----------+
| 24 |
+----------+
1 row in set (0.59 sec)

mysql> select count(*) from test_archive where client_id = 50;
+----------+
| count(*) |
+----------+
| 24 |
+----------+
1 row in set (0.41 sec)

Archive引擎似乎表现还不错,接下来我们测试一下扫描包含300万行数据的表:

mysql> select count(*) from myisam_insert where c1 = 1;
+----------+
| count(*) |
+----------+
| 3000000 |
+----------+
1 row in set (1.05 sec)

mysql> select count(*) from archive_insert where c1 = 1;
+----------+
| count(*) |
+----------+
| 3000000 |
+----------+
1 row in set (2.20 sec)

mysql> flush status;
Query OK, 0 rows affected (0.00 sec)

mysql> select count(*) from archive_insert where c1 = 1;
+----------+
| count(*) |
+----------+
| 3000000 |
+----------+
1 row in set (0.00 sec)

mysql> show status like 'qcache_hits';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_hits | 1 |
+-------------------------+----------+

在上面的例子中,Archive表确实比MySQL表慢一些,但是它也在大约2秒的时间里完成了扫描。另外这个例子也表明,Archive表的扫描结果被放入了查询缓冲区。所以相同的查询请求几乎是立即得到回复(因为缓存命中)。

读取数据的时候,Archive引擎启用了一种称为“快照”的技术,这一点和InnoDB很相似。所以大量的并发读取操作不会阻止写入操作的执行。Archive表使用行锁定技术,这一点也和InnoDB一样。

Archive表的性能是否可能超过MyISAM?答案是肯定的。根据MySQL工程师的资料,当表内的数据达到1.5GB这个量级,CPU又比较快的时候,Archive表的执行性能就会超越MyISAM表。因为这个时候,CPU会取代I/O子系统成为性能瓶颈。别忘了Archive表比其他任何类型的表执行的物理I/O操作都要少。

记住一点,Archive存储引擎设计的出发点不仅是追求SQL查询时卓越的性能,而且更重要的是为备份提供便利。当我们需要备份历史数据的时候,Archive引擎能在实质上减少需要转移的数据量。

较小的空间占用也能在你移植MySQL数据的时候发挥作用。当你需要把数据从一台MySQL服务器转移到另一台的时候,Archive表可以方便地移植到新的MySQL环境,你只需将保存Archive表的底层文件复制过去就可以了。

Continue Reading

MySQL5.0 Archive 存储引擎 (1) – 背景和简介

背景

一直以来,数据库专家都为企业中飞速增长的商业数据所困扰。工业分析数据正以平均42%/年的速率递增,保守估计,某些地方增长速度已达百分之几百,且完全没有停止迹象。究竟是什么原因导致数据爆炸性地增长?

首先,企业都已意识到大量相关数据蕴含着巨大的价值,他们比从前任何时候都更愿意保留这些可以利用的数据。从决策层到执行层,几乎所有人都高度重视数据分析结果的战略价值。于是数据被导入数据仓库,商业情报人员不时地输入分析查询语句,为将来某个关键的商业决策搜集支持依据。

其次,政府章程,比如Sarbanes-Oxley法案、 HIPAA标准等,促成了一种通过保留不必要保留的操作记录来清查越权行为的习惯。为了避免违反联邦法案,企业、学校、非盈利组织都要求软件记录下操作员执行的每一个步骤,这自然为数据库管理员带来了巨大的负担——他们不得不管理这些漫无边际地增长的数据。

最后,政府还有一个让数据库专家摊上更多事情的职能,就是安全控制和数据审计。那些管理着海量数据仓库的企业官员常常得回答诸如“何人何时修改了什么”或者“何人何时查看了什么”这样的提问。那些拥有数以千计的员工,开展着不计其数的业务的企业,每天都会产生出大量的日志记录数据,而且必须将其好好保存。

为了帮助数据库专家应对数据爆炸的挑战,MySQL5.0引入了一种新的数据存储引擎,叫做Archive。这个先进的数据管理工具,让MySQL的专家们拥有了处理和管理海量数据的新式武器。

Archive存储引擎概览

MySQL5.0的Archive存储引擎是唯一一个被设计用来帮助数据库管理员对付企业和组织中的大量流水数据的存储引擎。让我们马上来看看那些令Archive存储引擎能轻松应对前述挑战的独有特性吧。

由于企业要管理大量无关联历史数据,“信息生命周期管理”的需要开始增强。信息生命周期管理(ILM)的基本方法是,将历史的数据和操作记录转移到离线存储仓库中,在必要的时候依然可以访问他们。 MySQL 5.0中新的Archive存储引擎是保存无关联数据和操作记录的完美解决方案。它使用了一种透明的压缩算法,让数据都保存在压缩的存档表中。

许多年来,MySQL的MyISAM数据表压缩技术提供了减少数据使用空间的方法。但Archive存储引擎比压缩的MyISAM更合适,因为:

  • MyISAM压缩技术要求数据库管理员离线操作,而Archive数据引擎无需数据库暂停服务。所以使用Archive能保证数据库无间断运行。
  • MyISAM的压缩需要myisampack工具在命令行中执行,而Archive的压缩只需要一个简单的数据库描述语言指令。
  • 压缩的MyISAM表是只读的,Archive则同时支持Select和Insert的操作。另外,Archive使用常量读的方式,所以读取操作不会锁定数据表,阻止写操作的执行。
  • 数据存储于Archive表比压缩的MyISAM更为高效,所以Archive的投资回报率更高。

那些被数据存档和安全备案任务所困扰的MySQL数据库管理员们会喜欢Archive数据存储引擎,因为他们将不再需要将历史数据备份到磁带以节省存档开销。而且,历史数据的价值也可以得到提升,因为调用这些数据的时候无需先将数据从磁带还原到磁盘。

除了拥有简单易用的压缩特性之外,Archive存储引擎也是数据审计的最佳选择。Archive表只支持SELECT和INSERT操作,系统安全官员和审计员一定会非常乐于这样,毕竟审计工作要求严格保证原始数据不可更改。Archive表正好提供了这种限制——数据既无法修改又不能选择性地删除,换句话说,不可人为干预。

其他数据库厂商也提供数据表或数据库的压缩功能,但没有一个像MySQL的Archive存储引擎一样是直接为数据存档审计设计的。比如,Oracle从9.2版开始,引入了“压缩表”,但是它不具备数据审计的特性——只支持SELECT和INSERT。微软的SQL Server数据库管理员可以利用操作系统的压缩功能来减少数据库文件占用的磁盘空间量,不过偶有报告的数据损坏的情况吓阻了许多人。MySQL的Archive表的使用更为简单,完全不需要操作系统介入,能有效预防数据变更,保障数据可靠安全。

所以,不论是数据仓库、数据存档、还是数据审计的应用场合,全新的MySQL5.0 Archive存储引擎都是保障数据安全储存的最佳选择。在诸多数据存储产品中,它拥有最高的投资回报率。

本文自MySQL网站文章翻译而来,您可以查看原文下一篇文章将继续介绍Archive存储引擎的试用情况。

Continue Reading

国学操?要你命三千!

成都创作全国首套小学“国学操”

模仿古代“请”、“让”、“孝”等系列动作,编制成一套极有古典韵味的体操!再配上《渔舟唱晚》的背景音乐,一边“做操”一边大声朗诵国学名篇或者名句……昨日,记者获悉,我市双眼井小学耗时数月,创作出了一套“国学操”,将体操和国学的诵读融二为一。据悉,这是目前全国第一套“国学操”。阅读全文

读完此新闻,发现还真是弘扬国粹——形式大于内容。都知道做广播体操是强身健体,朗诵名篇名句是识字读书,学习礼节是提升涵养,三者完全风马牛不相及,随便凑在一起,简直就是“要你命三千”。小学生果然很惨,被当做实验品。不知道这样一套让孩子们听着《渔舟唱晚》,念着“凡是人,皆须爱,天同覆,地同载”,做着“请”的动作的国学操,如何能同时起到强健体魄,陶冶情操,修身养性的作用。

PS:不知道试点学校早操和早读是不是可以合并。

Continue Reading

从优酷转土豆

本来一直在优酷看网上视频的,电影电视剧都是如此。今晚优酷居然搞什么Nokia的现场会直播,害的我不能看视频了,只好转向土豆。转了才发现土豆做的比优酷好,界面很易用,而且下面的网友评论也比较高质量。下载了一个土豆的p2p前端,于是完全没有“卡”这个概念了。据说iTudou还能把喜欢的视频下载下来,转换成适合手机播放的格式,不过对我来说这个功能基本没有什么用了。

单从视频播放的角度来说,优酷还是很有优势的,毕竟优酷的播放相当流畅,很少出现服务器资源不足带来的卡死问题。不过长视频播放的时候,确实会偶尔出现缓冲的中间就停止的情况。土豆需要外挂前端程序来解决的问题,优酷已经尽量避免了,但依然还有避不开的网络拥堵。土豆的p2p前端付出了浏览器兼容性的代价,用非IE浏览器观看土豆的视频,基本是缓冲3分钟看一分钟。

社区特性方面土豆比优酷要好一些,可以设置自己的关注的视频列表,可以方便地和其他人交流对视频的看法。优酷似乎只有一个简单的留言板,基本上总是充斥着“顶”这样的无意义言论。

至于我是否以后全面转向土豆,还是先看看土豆的视频内容类型是否合我胃口再说吧。

Continue Reading