这配置以后外星人13能升级配置吗空间大不大,最高能上什么u?

https://blog.csdn.net/
https://static-blog.csdn.net/images/logo.gif
https://blog.csdn.net/u
https://blog.csdn.net/
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
50多条实用mysql数据库优化建议
数据挖掘入门与实战 公众号: datadw
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
缺省情况下建立的索引是非群集索引,但有时它并不是最佳的。在非群集索引下,数据在物理上随机存放在数据页上。合理的索引设计要建立在对各种查询的分析和预测上。一般来说:
a.有大量重复值、且经常有范围查询( & ,& ,& =,& =)和 order by、group by 发生的列,可考虑建立集群索引;
b.经常同时存取多列,且每列都含有重复值可考虑建立组合索引, 选择度高的列建议作为索引的第一个字段
c.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。索引虽有助于提高性能但 不是索引越多越好,恰好相反过多的索引会导致系统低效。用户在表中每加进一个索引,维护索引集合就 要做相应的更新工作。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,
Sql 代码 : select id from
可以在 num 上设置默认值 0,确保表中 num 列没有 null 值,然后这样查询:
Sql 代码 : select id from t where num=0;
3.应尽量避免在 where 子句中使用!=或&&操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,
Sql 代码 : select id from t where num=10 or num=20;
可以这样查询:
Sql 代码 : select id from t where num=10 union all select id from t where num=20;
5.in 和 not in 也要慎用,否则会导致全表扫描,如:
Sql 代码 : select id from t where num in(1,2,3);
对于连续的数值,能用 between 就不要用 in 了:
Sql 代码 : select id from t where num between 1 and 3;
6.下面的查询也将导致全表扫描:
Sql 代码 : select id from t where name like '%c%';
若要提高效率,可以考虑全文检索。
7.如果在 where 子句中使用参数,也会导致全表扫描。因为 SQL 只有在运行时才会解析局部变量,但优 化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计 划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
Sql 代码 : select id from t where num=@
可以改为强制查询使用索引:
Sql 代码 : select id from t with(index(索引名)) where num=@
8.应尽量避免在 where 子句中对字段进行表达式操作, 这将导致引擎放弃使用索引而进行全表扫描。
Sql 代码 : select id from t where num/2=100;
可以这样查询:
Sql 代码 : select id from t where num=100*2;
9.应尽量避免在 where 子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
Sql 代码 : select id from t where substring(name,1,3)='abc';#name 以 abc 开头的 id
Sql 代码 : select id from t where name like 'abc%';
10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用 索引。
11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件 时才能保证系统使用该索引, 否则该索引将不会 被使用, 并且应尽可能的让字段顺序与索引顺序相一致。
12.不要写一些没有意义的查询,如需要生成一个空表结构:
Sql 代码 : select col1,col2 into #t from t where 1=0;
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
Sql 代码 : create table #t(…);
13.很多时候用 exists 代替 in 是一个好的选择:
Sql 代码 : select num from a where num in(select num from b);
用下面的语句替换:
Sql 代码 : select num from a where exists(select 1 from b where num=a.num);
14.并不是所有索引对查询都有效,SQL 是根据表中数据来进行查询优化的,当索引列有大量数据重复时, SQL 查询可能不会去利用索引,如一表中有字段 ***,male、female 几乎各一半,那么即使在 *** 上建 了索引也对查询效率起不了作用。
15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过 6 个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
16.应尽可能的避免更新 clustered 索引数据列, 因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。
17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并 会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言 只需要比较一次就够了。
18.尽可能的使用 varchar/nvarchar 代替 char/nchar , 因为首先变长字段存储空间小, 可以节省存储空间, 其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
21.避免频繁创建和删除临时表,以减少系统表资源的消耗。
22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用 表中的某个数据集时。但是,对于一次性事件, 最好使用导出表。
23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先 create table,然后 insert.
24.如果使用到了临时表, 在存储过程的最后务必将所有的临时表显式删除, 先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过 1 万行,那么就应该考虑改写。
26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更 有效。
27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF .无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
29.尽量避免大事务操作,提高系统并发能力。
30.定期分析表和检查表。
分析表的语法:ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tb1_name[, tbl_name]...
以上语句用于分析和存储表的关键字分布,分析的结果将可以使得系统得到准确的统计信息,使得SQL能够生成正确的执行计划。如果用户感觉实际执行计 划并不是预期的执行计划,执行一次分析表可能会解决问题。在分析期间,使用一个读取锁定对表进行锁定。这对于MyISAM,DBD和InnoDB表有作 用。
例如分析一个数据表:analyze table table_name 检查表的语法:CHECK TABLE tb1_name[,tbl_name]...[option]...option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
检查表的作用是检查一个或多个表是否有错误,CHECK TABLE 对MyISAM 和 InnoDB表有作用,对于MyISAM表,关键字统计数据被更新
CHECK TABLE 也可以检查视图是否有错误,比如在视图定义中被引用的表不存在。
31.定期优化表。
优化表的语法:OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tb1_name [,tbl_name]...
如果删除了表的一大部分,或者如果已经对含有可变长度行的表(含有 VARCHAR、BLOB或TEXT列的表)进行更多更改,则应使用OPTIMIZE TABLE命令来进行表优化。这个命令可以将表中的空间碎片进行合并,并且可以消除由于删除或者更新造成的空间浪费,但OPTIMIZE TABLE 命令只对MyISAM、 BDB 和InnoDB表起作用。
例如: optimize table table_name
注意: analyze、check、optimize执行期间将对表进行锁定,因此一定注意要在MySQL数据库不繁忙的时候执行相关的操作。32.存储引擎的选择如果数据表需要事务处理,应该考虑使用InnoDB,因为它完全符合ACID特性。如果不需要事务处理,使用默认存储引擎MyISAM是比较明智的。
MyISAM适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。 InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。
34、EXPLAIN 你的 SELECT 查询
使用 EXPLAIN 关键字可以让你知道MySQL是如何处理你的SQL语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。
EXPLAIN 的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的……等等,等等。
挑一个你的SELECT语句(推荐挑选那个最复杂的,有多表联接的),把关键字EXPLAIN加到前面。你可以使用phpmyadmin来做这个事。然后,你会看到一张表格。下面的这个示例中,我们忘记加上了group_id索引,并且有表联接:
当我们为 group_id 字段加上索引后:
我们可以看到,前一个结果显示搜索了 7883 行,而后一个只是搜索了两个表的 9 和 16 行。查看rows列可以让我们找到潜在的性能问题。
35、 当只要一行数据时使用 LIMIT 1
当你查询表的有些时候,你已经知道结果只会有一条结果,但因为你可能需要去fetch游标,或是你也许会去检查返回的记录数。
在这种情况下,加上 LIMIT 1 可以增加性能。这样一样,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。
下面的示例,只是为了找一下是否有“中国”的用户,很明显,后面的会比前面的更有效率。(请注意,第一条中是Select *,第二条是Select 1)
// 没有效率的:$r = mysql_query("SELECT * FROM user WHERE country = 'China'");if (mysql_num_rows($r) & 0) {// ...}// 有效率的:$r = mysql_query("SELECT 1 FROM user WHERE country = 'China' LIMIT 1");if (mysql_num_rows($r) & 0) {// ...}
36. 在Join表的时候使用相同类型的列,并将其索引
如果你的应用程序有很多 JOIN 查询,你应该确认两个表中Join的字段是被建过索引的。这样,MySQL内部会启动为你优化Join的SQL语句的机制。
而且,这些被用来Join的字段,应该是相同的类型的。例如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行。(两个表的字符集有可能不一样) // 在state中查找company$r = mysql_query("SELECT company_name
FROM usersLEFT JOIN companies ON (users.state = companies.state)WHERE users.id = $user_id");
两个 state 字段应该是被建过索引的,而且应该是相当的类型,相同的字符集。
37、千万不要 ORDER BY RAND()
想打乱返回的数据行?随机挑一个数据?真不知道谁发明了这种用法,但很多新手很喜欢这样用。但你确不了解这样做有多么可怕的性能问题。
如 果你真的想把返回的数据行打乱了,你有N种方法可以达到这个目的。这样使用只让你的数据库的性能呈指数级的下降。这里的问题是:MySQL会不得不去执行 RAND()函数(很耗CPU时间),而且这是为了每一行记录去记行,然后再对其排序。就算是你用了Limit 1也无济于事(因为要排序)
下面的示例是随机挑一条记录
// 千万不要这样做:$r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1");// 这要会更好:$r = mysql_query("SELECT count(*) FROM user");$d = mysql_fetch_row($r);$rand = mt_rand(0,$d[0] - 1);$r = mysql_query("SELECT username FROM user LIMIT $rand, 1");
38. 永远为每张表设置一个ID
我们应该为数据库里的每张表都设置一个ID做为其主键,而且最好的是一个INT型的(推荐使用UNSIGNED),并设置上自动增加的 AUTO_INCREMENT标志。
就算是你 users 表有一个主键叫 “email”的字段,你也别让它成为主键。使用 VARCHAR 类型来当主键会使用得性能下降。另外,在你的程序中,你应该使用表的ID来构造你的数据结构。
而且,在MySQL数据引擎下,还有一些操作需要使用主键,在这些情况下,主键的性能和设置变得非常重要,比如,集群,分区……
在 这里,只有一个情况是例外,那就是“关联表”的“外键”,也就是说,这个表的主键,通过若干个别的表的主键构成。我们把这个情况叫做“外键”。比如:有一 个“学生表”有学生的ID,有一个“课程表”有课程ID,那么,“成绩表”就是“关联表”了,其关联了学生表和课程表,在成绩表中,学生ID和课程ID叫 “外键”其共同组成主键。
39. 从 PROCEDURE ANALYSE() 取得建议
PROCEDURE ANALYSE() 会让 MySQL 帮你去分析你的字段和其实际的数据,并会给你一些有用的建议。只有表中有实际的数据,这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础的。
例 如,如果你创建了一个 INT 字段作为你的主键,然而并没有太多的数据,那么,PROCEDURE ANALYSE()会建议你把这个字段的类型改成 MEDIUMINT 。或是你使用了一个 VARCHAR 字段,因为数据不多,你可能会得到一个让你把它改成 ENUM 的建议。这些建议,都是可能因为数据不够多,所以决策做得就不够准。
在phpmyadmin里,你可以在查看表时,点击 “Propose table structure” 来查看这些建议
一定要注意,这些只是建议,只有当你的表里的数据越来越多时,这些建议才会变得准确。一定要记住,你才是最终做决定的人。
40. 字段尽可能的使用 NOT NULL约束
除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。这看起来好像有点争议,请往下看。
首先,问问你自己“Empty”和“NULL”有多大的区别(如果是INT,那就是0和NULL)?如果你觉得它们之间没有什么区别,那么你就不要使用NULL。(你知道吗?在 Oracle里,NULL 和 Empty 的字符串是一样的!)
不要以为 NULL 不需要空间,其需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。 当然,这里并不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。
下面摘自MySQL自己的文档:
“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”
如果你要保存 NULL,手动去设置它,而不是把它设为默认值。 建议用用0、特殊值或空串代替NULL值
41. Prepared Statements
Prepared Statements很像存储过程,是一种运行在后台的SQL语句集合,我们可以从使用 prepared statements 获得很多好处,无论是性能问题还是安全问题。
Prepared Statements 可以检查一些你绑定好的变量,这样可以保护你的程序不会受到“SQL注入式”攻击。当然,你也可以手动地检查你的这些变量,然而,手动的检查容易出问题, 而且很经常会被程序员忘了。当我们使用一些framework或是ORM的时候,这样的问题会好一些。
在性能方面,当一个相同的查询被使用多次的时候,这会为你带来可观的性能优势。你可以给这些Prepared Statements定义一些参数,而MySQL只会解析一次。
虽然最新版本的MySQL在传输Prepared Statements是使用二进制形势,所以这会使得网络传输非常有效率。
当然,也有一些情况下,我们需要避免使用Prepared Statements,因为其不支持查询缓存。但据说版本5.1后支持了。
42. 把IP地址存成 UNSIGNED INT
很 多程序员都会创建一个 VARCHAR(15) 字段来存放字符串形式的IP而不是整形的IP。如果你用整形来存放,只需要4个字节,并且你可以有定长的字段。而且,这会为你带来查询上的优势,尤其是当 你需要使用这样的WHERE条件:IP between ip1 and ip2。
我们必需要使用UNSIGNED INT,因为 IP地址会使用整个32位的无符号整形。
而你的查询,你可以使用 INET_ATON() 来把一个字符串IP转成一个整形,并使用 INET_NTOA() 把一个整形转成一个字符串IP。在PHP中,也有这样的函数 ip2long() 和 long2ip()。
1 $r = "UPDATE users SET ip = INET_ATON('{$_SERVER['REMOTE_ADDR']}') WHERE user_id = $user_id";
43. 固定长度的表会更快
如 果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”。 例如,表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。
固定长度的表会提高性能,因为MySQL搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键。
并且,固定长度的表也更容易被缓存和重建。不过,唯一的副作用是,固定长度的字段会浪费一些空间,因为定长的字段无论你用不用,他都是要分配那么多的空间。
使用“垂直分割”技术(见下一条),你可以分割你的表成为两个一个是定长的,一个则是不定长的。
45. 垂直分割表
“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。(以前,在银行做过项目,见过一张表有100多个字段,很恐怖)
示 例一:在Users表中有一个字段是家庭地址,这个字段是可选字段,相比起,而且你在数据库操作的时候除了个人信息外,你并不需要经常读取或是改写这个字 段。那么,为什么不把他放到另外一张表中呢? 这样会让你的表有更好的性能,大家想想是不是,大量的时候,我对于用户表来说,只有用户ID,用户名,口令,用户角色等会被经常使用。小一点的表总是会有 好的性能。
示例二: 你有一个叫 “last_login” 的字段,它会在每次用户登录时被更新。但是,每次更新时会导致该表的查询缓存被清空。所以,你可以把这个字段放到另一个表中,这样就不会影响你对用户 ID,用户名,用户角色的不停地读取了,因为查询缓存会帮你增加很多性能。
另外,你需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去Join他们,不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降。
46. 拆分大的 DELETE 或 INSERT 语句
如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,你需要非常小心,要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。
Apache 会有很多的子进程或线程。所以,其工作起来相当有效率,而我们的服务器也不希望有太多的子进程,线程和数据库链接,这是极大的占服务器资源的事情,尤其是内存。
如果你把你的表锁上一段时间,比如30秒钟,那么对于一个有很高访问量的站点来说,这30秒所积累的访问进程/线程,数据库链接,打开的文件数,可能不仅仅会让你泊WEB服务Crash,还可能会让你的整台服务器马上掛了。
所以,如果你有一个大的处理,你定你一定把其拆分,使用 LIMIT 条件是一个好的方法。下面是一个示例:
while (1) {//每次只做1000条mysql_query("DELETE FROM logs WHERE log_date &= '' LIMIT 1000");if (mysql_affected_rows() == 0) {// 没得可删了,退出!}// 每次都要休息一会儿usleep(50000);}
47. 越小的列会越快
对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈。所以,把你的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问。
参看 MySQL 的文档 Storage Requirements 查看所有的数据类型。
如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多。
当然,你也需要留够足够的扩展空间,不然,你日后来干这个事,你会死的很难看,参看Slashdot的例子( 日),一个简单的ALTER TABLE语句花了3个多小时,因为里面有一千六百万条数据。
48. 使用一个对象关系映射器(Object Relational Mapper)
使用 ORM (Object Relational Mapper),你能够获得可靠的性能增涨。一个ORM可以做的所有事情,也能被手动的编写出来。但是,这需要一个高级专家。
ORM 的最重要的是“Lazy Loading”,也就是说,只有在需要的去取值的时候才会去真正的去做。但你也需要小心这种机制的副作用,因为这很有可能会因为要去创建很多很多小的查 询反而会降低性能。 ORM 还可以把你的SQL语句打包成一个事务,这会比单独执行他们快得多得多。
49. 小心“永久链接”
“永 久链接”的目的是用来减少重新创建MySQL链接的次数。当一个链接被创建了,它会永远处在连接的状态,就算是数据库操作已经结束了。而且,自从我们的 Apache开始重用它的子进程后——也就是说,下一次的HTTP请求会重用Apache的子进程,并重用相同的 MySQL 链接。
50、范围列(&,&,between and)可以用到索引,但是范围列后面的列无法用到索引。同时,索引最多用于一个范围列,因此如果查询条件中有两个范围列则无法全用到索引
51、如果需要在大字段上建立索引,可以考虑使用前缀索引。
建立前缀索引的语法为:
ALTER TABLE table_name ADD KEY(column_name(prefix_length));
52、 将大字段、访问频率低的字段拆分到单独的表中存储,分离冷热数据,有利于有效利用缓存,防止读入无用的冷数据,较少磁盘IO,同时保证热数据常驻内存提高缓存命中率。
53、 MYSQL的新增和修改列的操作相当于重建表,表设计要一步到位,尽量避免大表的DDL操作。 (TIPS:可以预定义一些列留作将来业务扩展,如:当前只需要10个字段,考虑到未来发展,可以预留10个字段,表上总共创建20个字段)
54、为了降低索引维护成本,禁止冗余索引,增大IO压力。(a,b,c)、(a,b),后者为冗余索引。可以利用前缀索引来达到加速目的,减轻维护负担。
55、WHERE子句中的数据扫描不超过表总数据量的30%
如何选择prefix_length的长度,具体参考:前缀索引,一种优化索引大小的解决方案
http://www.cnblogs.com/studyzy/p/4310653.html
》、在海量查询时尽量少用格式转换。
》、任何对列的操作都将导致表扫描,它包括数据库教程函数、计算表达式等等,查询时要尽可能将操作移 至等号右边。
》、IN、OR 子句常会使用工作表,使索引失效。如果不产生大量重复值,可以考虑把子句拆开。拆开的子 句中应该包含索引。
》、尽量少用 CLOB、TEXT、BLOB大类型
》、如果你的数据只有你所知的少量的几个。最好使用 ENUM 类型
ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。
如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。
MySQL也有一个“建议”(见第十条)告诉你怎么去重新组织你的表结构。当你有一个 VARCHAR 字段时,这个建议会告诉你把其改成 ENUM 类型。使用 PROCEDURE ANALYSE() 你可以得到相关的建议。
》、合理用运分库、分表与分区表提高数据存放和提取速度。具体参考:Mysql分表和分区的区别、分库分表区别
http://www.cnblogs.com/langtianya/p/4997768.html
作者:u 发表于
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
MySQL CPU 使用率高的原因和解决方法
更新时间: 13:25:52
用户在使用 MySQL 实例时,会遇到 CPU 使用率过高甚至达到 100% 的情况。本文将介绍造成该状况的常见原因以及解决方法,并通过 CPU 使用率为 100% 的典型场景,来分析引起该状况的原因及其相应的解决方案。
系统执行应用提交查询(包括数据修改操作)时需要大量的逻辑读(逻辑 IO,执行查询所需访问的表的数据行数),所以系统需要消耗大量的 CPU 资源以维护从存储系统读取到内存中的数据一致性。
说明:大量行锁冲突、行锁等待或后台任务也有可能会导致实例的 CPU 使用率过高,但这些情况出现的概率非常低,本文不做讨论。
本文通过一个简化的模型来说明系统资源、语句执行成本以及 QPS(Query Per Second 每秒执行的查询数)之间的关系:
条件:应用模型恒定(应用没有修改)。
avg_lgc_io:执行每条查询需要的平均逻辑 IO。
total_lgc_io:实例的 CPU 资源在单位时间内能够处理的逻辑 IO 总量。
关系公式:total_lgc_io
= avg_lgc_io x QPS -- 单位时间 CPU 资源 = 查询执行的平均成本 x 单位时间执行的查询数量
工具提供了几种辅助排查并解决实例性能问题的功能,主要有:
实例诊断报告
SQL 窗口提供的查询优化建议和查看执行计划
其中,实例诊断报告是排查和解决 MySQL 实例性能问题的最佳工具。无论何种原因导致的性能问题,建议您首先参考下实例诊断报告,尤其是诊断报告中的 SQL 优化、会话列表和慢 SQL 汇总分。
另外,如果您需要阿里云的技术支持来解决 CPU 使用率高的状况,请参见 。
避免出现 CPU 使用率达到 100% 的一般原则
设置 CPU 使用率告警,实例 CPU 使用率保证一定的冗余度。
应用设计和开发过程中,要考虑查询的优化,遵守 MySQL 优化的一般优化原则,降低查询的逻辑 IO,提高应用可扩展性。
新功能、新模块上线前,要使用生产环境数据进行压力测试(可以考虑使用阿里云 PTS 压力测试工具)。
新功能、新模块上线前,建议使用生产环境数据进行回归测试。
建议经常关注和使用 DMS 中的诊断报告。
注意:关于如何访问 DMS 中的诊断报告,请参见 。
以 CPU 使用率为 100% 的典型场景为例,本文介绍了两个引起该状况的原因及其解决方案,即应用负载(QPS)高和查询执行成本(查询访问表数据行数 avg_lgc_io)高。其中,由于查询执行成本高(查询访问表数据行数多)而导致实例 CPU 使用率高是 MySQL 非常常见的问题。
应用负载(QPS)高
特征:实例的 QPS(每秒执行的查询次数)高,查询比较简单、执行效率高、优化余地小。
表现:没有出现慢查询(或者慢查询不是主要原因),且 QPS 和 CPU 使用率曲线变化吻合。
常见场景:该状况常见于应用优化过的在线事务交易系统(例如订单系统)、高读取率的热门 Web 网站应用、第三方压力工具测试(例如 Sysbench)等。
对于由应用负载高导致的 CPU 使用率高的状况,使用 SQL 查询进行优化的余地不大,建议您从应用架构、实例规格等方面来解决,例如:
升级实例规格,增加 CPU 资源。
增加只读实例,将对数据一致性不敏感的查询(比如商品种类查询、列车车次查询)转移到只读实例上,分担主实例压力。
使用阿里云 DRDS 产品,自动进行分库分表,将查询压力分担到多个 RDS 实例上。
使用阿里云 Memcache 或者云 Redis 产品,尽量从缓存中获取常用的查询结果,减轻 RDS 实例的压力。
对于查询数据比较静态、查询重复度高、查询结果集小于 1 MB 的应用,考虑开启查询缓存(Query Cache)。
注意:能否从开启查询缓存(Query Cache)中获益需要经过测试,具体设置请参见 。
定期归档历史数据、采用分库分表或者分区的方式减小查询访问的数据量。
尽量优化查询,减少查询的执行成本(逻辑 IO,执行需要访问的表数据行数),提高应用可扩展性。
查询执行成本(查询访问表数据行数 avg_lgc_io)高
特征:实例的 QPS(每秒执行的查询次数)不高;查询执行效率低、执行时需要扫描大量表中数据、优化余地大。
表现:存在慢查询,QPS 和 CPU 使用率曲线变化不吻合。
原因分析:由于查询执行效率低,为获得预期的结果即需要访问大量的数据(平均逻辑 IO高),在 QPS 并不高的情况下(例如网站访问量不大),就会导致实例的 CPU 使用率高。
解决该状况的原则是:定位效率低的查询、优化查询的执行效率、降低查询执行的成本。
通过如下方式定位效率低的查询:
命令查看当前执行的查询,如下图所示:
对于查询时间长、运行状态(State 列)是“Sending data”、“Copying to tmp table”、“Copying to tmp table on disk”、“Sorting result”、“Using filesort”等都可能是有性能问题的查询(SQL)。
若在 QPS 高导致 CPU 使用率高的场景中,查询执行时间通常比较短,show
命令或实例会话中可能会不容易捕捉到当前执行的查询。您可以通过执行如下命令进行查询:
explain select b.* from perf_test_no_idx_01 a, perf_test_no_idx_02 b where a.created_on &= 2015-01-01 and a.detail = b.detail
您可以通过执行类似 kill
; 的命令来终止长时间执行的会话,终止会话请参见 。关于长时间执行会话的管理,请参见
通过 DMS 查看当前执行的查询,查询步骤如下:
在 DMS 控制台上。
选择性能 & 实例会话,显示结果如下图所示:
从上图可以看出,有 10 个会话在执行下面这个查询:
select b.* from perf_test_no_idx_01 a, perf_test_no_idx_02 b where a.created_on&= '' and a.detail= b.detail;
单击 SQL 列中的查询文本,即可显示完整的查询和其执行计划,如下图所示:
从上图可以看出,在该查询的执行计划中,系统对两张约为 30 万行的数据表执行了全表扫描。由于两张表是联接操作,这个查询的执行成本(逻辑 IO)约为 298267 x 298839 = 89,133,812,013(大概 900 亿),所以查询会执行相当长的时间并且多个会话会导致实例 CPU 使用率达到 100%(对于同样规格的实例,如果是优化良好的查询,QPS 可以达到 21000;而当前 QPS 仅为 5)。
得到需要优化的查询后,可以通过如下任意一种方式来获取查询的优化建议:
通过 DMS 的优化查询获取:
注意:对于 QPS 高和查询效率低的混合模式导致的 CPU 使用率高的问题,建议使用优化查询获取优化建议。
在 DMS 控制台上。
选择 SQL 操作 & SQL 窗口。
单击优化,即可得到优化建议,如下图所示:
通过 DMS 控制台上的诊断报告获取:
说明:诊断报告同样适用于排查历史实例 CPU 使用率高的问题。
在 DMS 控制台上。
选择性能 & 诊断报告。
单击发起诊断,即可创建一个针对当前实例运行情况的报告,如下图所示:
单击查看报告,查看优化建议。
注意:对于 CPU 使用率高的问题,建议关注诊断报告的 SQL 优化、会话列表和慢 SQL 汇总部分。
根据优化建议,添加索引,查询执行成本就会大幅减少(如下图所示,从 900 亿行减小到 30 万行,查询成本降低 30 万倍),实例 CPU 使用率 100% 的问题解决。
本文导读目录
本文导读目录
作者:u 发表于
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
前段时间,公司的多台主要的生产环境服务器发生了cpu频繁占满,然后tomcat歇菜的情况。查看资源占用情况,发现是一个以root起的httpd.conf的进程在占用,尝试kill,但愈演愈烈。百度后觉得可能是当初装的nagios的漏洞导致。不久,报出了Struts2的()漏洞。再次查看服务器日志,发现也确有出现利用此漏洞的攻击。遂决定重装了服务器。并对jar包升级。
项目原struts包版本2.3.15.1
根据官方解决方案,目标版本 2.3.32
附 本次更换的jar包版本:
freemarker-2.3.22.jar
commons-lang3-3.2.jar
commons-io-2.2.jar
commons-lang-2.4.jar
commons-fileupload-1.3.2.jar
struts2-convention-plugin-2.3.32.jar
struts2-core-plugin-2.3.32.jar
struts2-spring-plugin-2.3.32.jar
xwork-core-2.3.32.jar
struts2-json-plugin-2.3.32.jar(我没有换因为用的fastjson,如果之前有依赖应该也要换)
然儿,替换完后工程正常启动(至少看起来如此),但是访问返回的都是404。忽略的是升级struts2版本基本就会更改它的配置文件。
&constant name="struts.enable.DynamicMethodInvocation" value="true" /&
如果没有配置这个你会发现。你原来的项目报404错误,这个是开启或禁止调用动态方法,如果是false,则不会有动态调用产生的404错误。
在struts.xml添加这条配置信息,ok,服务器访问正常
作者:u 发表于
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
LocalDateTime –& Date
LocalDateTime date = LocalDateTime.now().plus(2, ChronoUnit.YEARS);
System.out.println(new Date());
Date da = Date.from(Instant.from(date.atZone(ZoneId.systemDefault())));
System.out.println(da);
Date –& LocalDateTime
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
作者:u 发表于
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
Logstash是一个接收,处理,转发日志的工具。支持系统日志,webserver日志,错误日志,应用日志,总之包括所有可以抛出来的日志类型。怎么样听起来挺厉害的吧?
在一个典型的使用场景下(ELK):用Elasticsearch作为后台数据的存储,kibana用来前端的报表展示。Logstash在其过程中担任搬运工的角色,它为数据存储,报表查询和日志解析创建了一个功能强大的管道链。Logstash提供了多种多样的 input,filters,codecs和output组件,让使用者轻松实现强大的功能。好了让我们开始吧
依赖条件:JAVA
Logstash运行仅仅依赖java运行环境(jre)。各位可以在命令行下运行java -version命令 显示类似如下结果:
java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
为了确保成功运行Logstash建议大家使用较近期的jre版本。 可以获取开源版本的jre在:http://openjdk.java.net 或者你可以在官网Oracle jdk版本:http://www.oracle.com/technetwork/java/index.html
一旦jre已经成功在你的系统中安装完成,我们就可以继续了
启动和运行Logstash的两条命令示例
第一步我们先下载Logstash
curl -O https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz
现在你应该有了一个叫logstash-1.4.2.tar.gz的文件了。 我们把它解压一下
tar zxvf logstash-1.4.2.tar.gz
cd logstash-1.4.2
现在我们来运行一下:
bin/logstash -e 'input { stdin { } } output { stdout {} }'
我们现在可以在命令行下输入一些字符,然后我们将看到logstash的输出内容:
hello world
T01:22:14.405+.0.0 hello world
Ok,还挺有意思的吧... 以上例子我们在运行logstash中,定义了一个叫"stdin"的input还有一个"stdout"的output,无论我们输入什么字符,Logstash都会按照某种格式来返回我们输入的字符。这里注意我们在命令行中使用了-e参数,该参数允许Logstash直接通过命令行接受设置。这点尤其快速的帮助我们反复的测试配置是否正确而不用写配置文件。
让我们再试个更有意思的例子。首先我们在命令行下使用CTRL-C命令退出之前运行的Logstash。现在我们重新运行Logstash使用下面的命令:
bin/logstash -e 'input { stdin { } } output { stdout { codec =& rubydebug } }'
我们再输入一些字符,这次我们输入"goodnight moon":
goodnight moon
"message" =& "goodnight moon",
"@timestamp" =& "T23:48:05.335Z",
"@version" =& "1",
"host" =& "my-laptop"
以上示例通过重新设置了叫"stdout"的output(添加了"codec"参数),我们就可以改变Logstash的输出表现。类似的我们可以通过在你的配置文件中添加或者修改inputs、outputs、filters,就可以使随意的格式化日志数据成为可能,从而订制更合理的存储格式为查询提供便利。
使用Elasticsearch存储日志
现在,你也许会说:"它看起来还挺高大上的,不过手工输入字符,并把字符从控制台回显出来。实际情况并不实用"。说的好,那么接下来我们将建立Elasticsearch来存储输入到Logstash的日志数据。如果你还没有安装Elasticsearch,你可以下载RPM/DEB包或者手动下载tar包,通过以下命令:
curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.1.tar.gz
tar zxvf elasticsearch-1.1.1.tar.gz
cd elasticsearch-1.1.1/
./bin/elasticsearch
注意 本篇文章实例使用Logstash 1.4.2和Elasticsearch 1.1.1。不同的Logstash版本都有对应的建议Elasticsearch版本。请确认你使用的Logstash版本!
更多有关安装和设置Elasticsearch的信息可以参考Elasticsearch官网。因为我们主要介绍Logstash的入门使用,Elasticsearch默认的安装和配置就已经满足我们要求。
言归正专,现在Elasticsearch已经运行并监听9200端口了(大家都搞定了,对吗?),通过简单的设置Logstash就可以使用Elasticsearch作为它的后端。默认的配置对于Logstash和Elasticsearch已经足够,我们忽略一些额外的选项来设置elasticsearch作为output:
bin/logstash -e 'input { stdin { } } output { elasticsearch { host =& localhost } }'
随意的输入一些字符,Logstash会像之前一样处理日志(不过这次我们将不会看到任何的输出,因为我们没有设置stdout作为output选项)
you know, for logs
我们可以使用curl命令发送请求来查看ES是否接收到了数据:
curl 'http://localhost:9200/_search?pretty'
返回内容如下:
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [ {
"_index" : "logstash-",
"_type" : "logs",
"_id" : "2ijaoKqARqGvbMgP3BspJA",
"_score" : 1.0, "_source" : {"message":"you know, for logs","@timestamp":"T18:45:09.862Z","@version":"1","host":"my-laptop"}
恭喜,至此你已经成功利用Elasticsearch和Logstash来收集日志数据了。
Elasticsearch 插件(题外话)
这里介绍另外一个对于查询你的Logstash数据(Elasticsearch中数据)非常有用的工具叫Elasticsearch-kopf插件。更多的信息请见Elasticsearch插件。安装elasticsearch-kopf,只要在你安装Elasticsearch的目录中执行以下命令即可:
bin/plugin -install lmenezes/elasticsearch-kopf
接下来访问 http://localhost:9200/_plugin/kopf 来浏览保存在Elasticsearch中的数据,设置及映射!
作为一个简单的例子来设置多重输出,让我们同时设置stdout和elasticsearch作为output来重新运行一下Logstash,如下:
bin/logstash -e 'input { stdin { } } output { elasticsearch { host =& localhost } stdout { } }'
当我们输入了一些词组之后,这些输入的内容回回显到我们的终端,同时还会保存到Elasticsearch!(可以使用curl和kopf插件来验证)。
默认配置 - 按照每日日期建立索引
你将发现Logstash可以足够灵巧的在Elasticsearch上建立索引... 每天会按照默认格式是logstash-YYYY.MM.DD来建立索引。在午夜(GMT),Logstash自动按照时间戳更新索引。我们可以根据追溯多长时间的数据作为依据来制定保持多少数据,当然你也可以把比较老的数据迁移到其他的地方(重新索引)来方便查询,此外如果仅仅是简单的删除一段时间数据我们可以使用Elasticsearch Curator。
接下来我们开始了解更多高级的配置项。在下面的章节,我们着重讨论logstash一些核心的特性,以及如何和logstash引擎交互的。
事件的生命周期
Inputs,Outputs,Codecs,Filters构成了Logstash的核心配置项。Logstash通过建立一条事件处理的管道,从你的日志提取出数据保存到Elasticsearch中,为高效的查询数据提供基础。为了让你快速的了解Logstash提供的多种选项,让我们先讨论一下最常用的一些配置。更多的信息,请参考Logstash事件管道。Inputs
input 及输入是指日志数据传输到Logstash中。其中常见的配置如下: file:从文件系统中读取一个文件,很像UNIX命令 "tail -0a"syslog:监听514端口,按照RFC3164标准解析日志数据redis:从redis服务器读取数据,支持channel(发布订阅)和list模式。redis一般在Logstash消费集群中作为"broker"角色,保存events队列共Logstash消费。lumberjack:使用lumberjack协议来接收数据,目前已经改为 logstash-forwarder。
Fillters 在Logstash处理链中担任中间处理组件。他们经常被组合起来实现一些特定的行为来,处理匹配特定规则的事件流。常见的filters如下: grok:解析无规则的文字并转化为有结构的格式。Grok 是目前最好的方式来将无结构的数据转换为有结构可查询的数据。有120多种匹配规则,会有一种满足你的需要。mutate:mutate filter 允许改变输入的文档,你可以从命名,删除,移动或者修改字段在处理事件的过程中。drop:丢弃一部分events不进行处理,例如:debug events。clone:拷贝
event,这个过程中也可以添加或移除字段。geoip:添加地理信息(为前台kibana图形化展示使用) Outputs
outputs是logstash处理管道的最末端组件。一个event可以在处理过程中经过多重输出,但是一旦所有的outputs都执行结束,这个event也就完成生命周期。一些常用的outputs包括: elasticsearch:如果你计划将高效的保存数据,并且能够方便和简单的进行查询...Elasticsearch是一个好的方式。是的,此处有做广告的嫌疑,呵呵。file:将event数据保存到文件中。graphite:将event数据发送到图形化组件中,一个很流行的开源存储图形化展示的组件。http://graphite.wikidot.com/。statsd:statsd是一个统计服务,比如技术和时间统计,通过udp通讯,聚合一个或者多个后台服务,如果你已经开始使用statsd,该选项对你应该很有用。
codecs 是基于数据流的过滤器,它可以作为input,output的一部分配置。Codecs可以帮助你轻松的分割发送过来已经被序列化的数据。流行的codecs包括 json,msgpack,plain(text)。 json:使用json格式对数据进行编码/解码multiline:将汇多个事件中数据汇总为一个单一的行。比如:java异常信息和堆栈信息 获取完整的配置信息,请参考 Logstash文档中 "plugin configuration"部分。
更多有趣Logstash内容
使用配置文件
使用-e参数在命令行中指定配置是很常用的方式,不过如果需要配置更多设置则需要很长的内容。这种情况,我们首先创建一个简单的配置文件,并且指定logstash使用这个配置文件。如我们创建一个文件名是"logstash-simple.conf"的配置文件并且保存在和Logstash相同的目录中。内容如下:
input { stdin { } }
elasticsearch { host =& localhost }
stdout { codec =& rubydebug }
接下来,执行命令:
bin/logstash -f logstash-simple.conf
我们看到logstash按照你刚刚创建的配置文件来运行例子,这样更加的方便。注意,我们使用-f参数来从文件获取而代替之前使用-e参数从命令行中获取配置。以上演示非常简单的例子,当然解析来我们继续写一些复杂一些的例子。
filters是一个行处理机制将提供的为格式化的数据整理成你需要的数据,让我们看看下面的一个例子,叫grok filter的过滤器。
input { stdin { } }
match =& { "message" =& "%{COMBINEDAPACHELOG}" }
match =& [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
elasticsearch { host =& localhost }
stdout { codec =& rubydebug }
执行Logstash按照如下参数:
bin/logstash -f logstash-filter.conf
现在粘贴下面一行信息到你的终端(当然Logstash就会处理这个标准的输入内容):
127.0.0.1 - - [11/Dec/:45 -0800] "GET /xampp/status.php HTTP/1.1" 200 3891 "http://cadenza/xampp/navi.php" "Mozilla/5.0 (M Intel Mac OS X 10.9; rv:25.0) Gecko/ Firefox/25.0"
你将看到类似如下内容的反馈信息:
"message" =& "127.0.0.1 - - [11/Dec/:45 -0800] \"GET /xampp/status.php HTTP/1.1\" 200 3891 \"http://cadenza/xampp/navi.php\" \"Mozilla/5.0 (M Intel Mac OS X 10.9; rv:25.0) Gecko/ Firefox/25.0\"",
"@timestamp" =& "T08:01:45.000Z",
"@version" =& "1",
"host" =& "cadenza",
"clientip" =& "127.0.0.1",
"ident" =& "-",
"auth" =& "-",
"timestamp" =& "11/Dec/:45 -0800",
"verb" =& "GET",
"request" =& "/xampp/status.php",
"httpversion" =& "1.1",
"response" =& "200",
"bytes" =& "3891",
"referrer" =& "\"http://cadenza/xampp/navi.php\"",
"agent" =& "\"Mozilla/5.0 (M Intel Mac OS X 10.9; rv:25.0) Gecko/ Firefox/25.0\""
正像你看到的那样,Logstash(使用了grok过滤器)能够将一行的日志数据(Apache的"combined log"格式)分割设置为不同的数据字段。这一点对于日后解析和查询我们自己的日志数据非常有用。比如:HTTP的返回状态码,IP地址相关等等,非常的容易。很少有匹配规则没有被grok包含,所以如果你正尝试的解析一些常见的日志格式,或许已经有人为了做了这样的工作。如果查看详细匹配规则,参考logstash grok patterns。
另外一个过滤器是date filter。这个过滤器来负责解析出来日志中的时间戳并将值赋给timestame字段(不管这个数据是什么时候收集到logstash的)。你也许注意到在这个例子中@timestamp字段是设置成December 11, 2013, 说明logstash在日志产生之后一段时间进行处理的。这个字段在处理日志中回添到数据中的,举例来说... 这个值就是logstash处理event的时间戳。
实用的例子
Apache 日志(从文件获取)
现在,让我们使用一些非常实用的配置... apache2访问日志!我们将从本地读取日志文件,并且通过条件设置处理满足我们需要的event。首先,我们创建一个文件名是logstash-apache.conf的配置文件,内容如下(你可以根据实际情况修改你的文件名和路径):
path =& "/tmp/access_log"
start_position =& beginning
if [path] =~ "access" {
mutate { replace =& { "type" =& "apache_access" } }
match =& { "message" =& "%{COMBINEDAPACHELOG}" }
match =& [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
elasticsearch {
host =& localhost
stdout { codec =& rubydebug }
接下来,我们按照上面的配置创建一个文件(在例子中是"/tmp/access.log"),可以将下面日志信息作为文件内容(也可以用你自己的webserver产生的日志):
71.141.244.242 - kurt [18/May/:10 -0700] "GET /admin HTTP/1.1" 301 566 "-" "Mozilla/5.0 (W U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/ Firefox/3.6.3"
134.39.72.245 - - [18/May/:18 -0700] "GET /favicon.ico HTTP/1.1" 200 1189 "-" "Mozilla/4.0 ( MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.; .NET CLR 3.5.30729; InfoPath.2; .NET4.0C; .NET4.0E)"
98.83.179.51 - - [18/May/:08 -0700] "GET /css/main.css HTTP/1.1" 200 1837 "http://www.safesand.com/information.htm" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:2.0.1) Gecko/ Firefox/4.0.1"
现在使用-f参数来执行一下上面的例子:
bin/logstash -f logstash-apache.conf
你可以看到apache的日志数据已经导入到ES中了。这里logstash会按照你的配置读取,处理指定的文件,任何后添加到文件的内容也会被捕获处理最后保存到ES中。此外,数据中type的字段值会被替换成"apache_access"(这个功能在配置中已经指定)。
这个配置只是让Logstash监控了apache access_log,但是在实际中往往并不够用可能还需要监控error_log,只要在上面的配置中改变一行既可以实现,如下:
path =& "/tmp/*_log"
现在你可以看到logstash处理了error日志和access日志。然而,如果你检查了你的数据(也许用elasticsearch-kopf),你将发现access_log日志被分成不同的字段,但是error_log确没有这样。这是因为我们使用了“grok”filter并仅仅配置匹配combinedapachelog日志格式,这样满足条件的日志就会自动的被分割成不同的字段。我们可以通过控制日志按照它自己的某种格式来解析日志,不是很好的吗?对吧。
此外,你也许还会发现Logstash不会重复处理文件中已经处理过得events。因为Logstash已经记录了文件处理的位置,这样就只处理文件中新加入的行数。漂亮!
我们利用上一个例子来介绍一下条件判断的概念。这个概念一般情况下应该被大多数的Logstash用户熟悉掌握。你可以像其他普通的语言一样来使用if,else if和else语句。让我们把每个event依赖的日志文件类型都标记出来(access_log,error_log其他以log结尾的日志文件)。
path =& "/tmp/*_log"
if [path] =~ "access" {
mutate { replace =& { type =& "apache_access" } }
match =& { "message" =& "%{COMBINEDAPACHELOG}" }
match =& [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
} else if [path] =~ "error" {
mutate { replace =& { type =& "apache_error" } }
mutate { replace =& { type =& "random_logs" } }
elasticsearch { host =& localhost }
stdout { codec =& rubydebug }
我想你已经注意到了,我们使用"type"字段来标记每个event,但是我们实际上没有解析"error"和”random"类型的日志... 而实际情况下可能会有很多很多类型的错误日志,如何解析就作为练习留给各位读者吧,你可以依赖已经存在的日志。
Ok,现在我们继续了解一个很实用的例子:syslog。Syslog对于Logstash是一个很长用的配置,并且它有很好的表现(协议格式符合RFC3164)。Syslog实际上是UNIX的一个网络日志标准,由客户端发送日志数据到本地文件或者日志服务器。在这个例子中,你根本不用建立syslog实例;我们通过命令行就可以实现一个syslog服务,通过这个例子你将会看到发生什么。
首先,让我们创建一个简单的配置文件来实现logstash+syslog,文件名是 logstash-syslog.conf
port =& 5000
type =& syslog
port =& 5000
type =& syslog
if [type] == "syslog" {
match =& { "message" =& "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }
add_field =& [ "received_at", "%{@timestamp}" ]
add_field =& [ "received_from", "%{host}" ]
syslog_pri { }
match =& [ "syslog_timestamp", "MMM
d HH:mm:ss", "MMM dd HH:mm:ss" ]
elasticsearch { host =& localhost }
stdout { codec =& rubydebug }
执行logstash:
bin/logstash -f logstash-syslog.conf
通常,需要一个客户端链接到Logstash服务器上的5000端口然后发送日志数据。在这个简单的演示中我们简单的使用telnet链接到logstash服务器发送日志数据(与之前例子中我们在命令行标准输入状态下发送日志数据类似)。首先我们打开一个新的shell窗口,然后输入下面的命令:
telnet localhost 5000
你可以复制粘贴下面的样例信息(当然也可以使用其他字符,不过这样可能会被grok filter不能正确的解析):
Dec 23 12:11:43 louis postfix/smtpd[31499]: connect from unknown[95.75.93.154]
Dec 23 14:42:56 louis named[16000]: client 199.48.164.7#64817: query (cache) 'amsterdamboothuren.com/MX/IN' denied
Dec 23 14:30:01 louis CRON[619]: (www-data) CMD (php /usr/share/cacti/site/poller.php &/dev/null 2&/var/log/cacti/poller-error.log)
Dec 22 18:28:06 louis rsyslogd: [origin software="rsyslogd" swVersion="4.2.0" x-pid="2253" x-info="http://www.rsyslog.com"] rsyslogd was HUPed, type 'lightweight'.
之后你可以在你之前运行Logstash的窗口中看到输出结果,信息被处理和解析!
"message" =& "Dec 23 14:30:01 louis CRON[619]: (www-data) CMD (php /usr/share/cacti/site/poller.php &/dev/null 2&/var/log/cacti/poller-error.log)",
"@timestamp" =& "T22:30:01.000Z",
"@version" =& "1",
"type" =& "syslog",
"host" =& "0:0:0:0:0:0:0:1:52617",
"syslog_timestamp" =& "Dec 23 14:30:01",
"syslog_hostname" =& "louis",
"syslog_program" =& "CRON",
"syslog_pid" =& "619",
"syslog_message" =& "(www-data) CMD (php /usr/share/cacti/site/poller.php &/dev/null 2&/var/log/cacti/poller-error.log)",
"received_at" =& " 22:49:22 UTC",
"received_from" =& "0:0:0:0:0:0:0:1:52617",
"syslog_severity_code" =& 5,
"syslog_facility_code" =& 1,
"syslog_facility" =& "user-level",
"syslog_severity" =& "notice"
恭喜各位,看到这里你已经成为一个合格的Logstash用户了。你将可以轻松的配置,运行Logstash,还可以发送event给Logstash,但是这个过程随着使用还会有很多值得深挖的地方。
作者:u 发表于
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
一、cacti概述
1. cacti是用php语言实现的一个软件,它的主要功能是用snmp服务获取数据,然后用rrdtool储存和更新数据,当用户需要查看数据的时候用rrdtool生成图表呈现给用户。因此,snmp和rrdtool是cacti的关键。Snmp关系着数据的收集,rrdtool关系着数据存储和图表的生成。
2. Mysql配合PHP程序存储一些变量数据并对变量数据进行调用,如:主机名、主机ip、snmp团体名、端口号、模板信息等变量。
3. snmp抓到数据不是存储在mysql中,而是存在rrdtool生成的rrd文件中(在cacti根目录的rra文件夹下)。rrdtool对数据的更新和存储就是对rrd文件的处理,rrd文件是大小固定的档案文件(Round Robin Archive),它能够存储的数据笔数在创建时就已经定义。
二、系统环境
1、Linux ubuntu-server 3.5.0-23-generic x86_64
三、apache、mysql、php安装
参考:http://developer.51cto.com/art/303.htm
四、cacti安装
enadmin@ubuntu-server:~$ apt-get update
enadmin@ubuntu-server:~$ sudo apt-get install cacti
通过这种方式安装会显示依赖包
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libperl5.14 libphp-adodb libsensors4 libsnmp-base libsnmp15 mysql-server php5-snmp rrdtool snmp
Suggested packages:
php5-ldap php5-adodb lm-sensors snmp-mibs-downloader
The following NEW packages will be installed:
cacti libperl5.14 libphp-adodb libsensors4 libsnmp-base libsnmp15 mysql-server php5-snmp rrdtool snmp
0 upgraded, 10 newly installed, 0 to remove and 113 not upgraded.
Need to get 4,205 kB/4,574 kB of archives.
After this operation, 12.6 MB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://mirrors.163.com/ubuntu/ precise-security/main php5-cli amd64 5.3.10-1ubuntu3.13 [3,051 kB]
Get:2 http://mirrors.163.com/ubuntu/ precise-security/main php5-mysql amd64 5.3.10-1ubuntu3.13 [76.6 kB]
Get:3 http://mirrors.163.com/ubuntu/ precise-security/main php5-gd amd64 5.3.10-1ubuntu3.13 [38.8 kB]
Get:4 http://mirrors.163.com/ubuntu/ precise-security/main libapache2-mod-php5 amd64 5.3.10-1ubuntu3.13 [3,137 kB]
Get:5 http://mirrors.163.com/ubuntu/ precise-security/main php5-common amd64 5.3.10-1ubuntu3.13 [1,774 kB]
Get:6 http://mirrors.163.com/ubuntu/ precise-security/main libsnmp-base all 5.4.3~dfsg-2.4ubuntu1.2 [217 kB]
Get:7 http://mirrors.163.com/ubuntu/ precise-security/main libsnmp15 amd64 5.4.3~dfsg-2.4ubuntu1.2 [1,334 kB]
Get:8 http://mirrors.163.com/ubuntu/ precise-security/main mysql-server all 5.5.38-0ubuntu0.12.04.1 [11.4 kB]
Get:9 http://mirrors.163.com/ubuntu/ precise-security/main php5-snmp amd64 5.3.10-1ubuntu3.13 [11.0 kB]
Get:10 http://mirrors.163.com/ubuntu/ precise-security/main snmp amd64 5.4.3~dfsg-2.4ubuntu1.2 [162 kB]
Fetched 9,813 kB in 16s (594 kB/s)
Preconfiguring packages ...
Package configuration
下面是安装过程截图
选中Apache2以后,接下来再会安装一些软件
在安装完上面内容以后,请进入以下地址再安装
enadmin@ubuntu-server:~$ sudo apt-get install snmpd
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 146 not upgraded.
Need to get 76.0 kB of archives.
After this operation, 267 kB of additional disk space will be used.
Get:1 http://mirrors.163.com/ubuntu/ precise-security/main snmpd amd64 5.4.3~dfsg-2.4ubuntu1.2 [76.0 kB]
Fetched 76.0 kB in 0s (97.6 kB/s)
Preconfiguring packages ...
Selecting previously unselected package snmpd.
(Reading database ... 59498 files and directories currently installed.)
Unpacking snmpd (from .../snmpd_5.4.3~dfsg-2.4ubuntu1.2_amd64.deb) ...
Processing triggers for ureadahead ...
ureadahead will be reprofiled on next reboot
Processing triggers for man-db ...
Setting up snmpd (5.4.3~dfsg-2.4ubuntu1.2) ...
update-rc.d: warning: snmpd stop runlevel arguments (1) do not match LSB Default-Stop values (0 1 6)
* Starting network management services:
enadmin@ubuntu-server:~$
测试snmp的服务
enadmin@ubuntu-server:~$ snmpwalk -v 1 -c public localhost .1.3.6.1.2.1.1.1.0
iso.3.6.1.2.1.1.1.0 = STRING: "Linux ubuntu-server 3.5.0-23-generic #35~precise1-Ubuntu SMP Fri Jan 25 17:13:26 UTC "
enadmin@ubuntu-server:~$
查看localhost的监控画面
在配置完毕上述内容以后,正常情况下应该可以看到cacti对于自身localhost的的默认监控了。我们进入到Graphs-&Tree Mode-&Default Tree-&Host:Localhost当中查看对于localhost的监控,如下图所示。
常见问题解决
问题1:cacti无法正常生成图片
在cacti当中看不到图片,通过Turn Off Graph Debug Mode.提示报错如下:
'/var/lib/cacti/rra/localhost_users_6.rrd': No such file or directory
解决方法:
这是因为权限问题原因导致的,系统无法生成相应的rrd文件,需要我们人工手动生成,具体操作方法如下:
Console-&System Utilities-&Rebuild Poller Cache
作者:u 发表于
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
[转载]原文出处:
一:场景描述
对于线上大流量服务或者需要上报日志的nginx服务,每天会产生大量的日志,这些日志非常有价值。可用于计数上报、用户行为分析、接口质量、性能监控等需求。但传统nginx记录日志的方式数据会散落在各自nginx上,而且大流量日志本身对磁盘也是一种冲击。
我们需要把这部分nginx日志统一收集汇总起来,收集过程和结果需要满足如下需求:
支持不同业务获取数据,如监控业务,数据分析统计业务,推荐业务等。
数据实时性
高性能保证
二:技术方案
得益于openresty和kafka的高性能,我们可以非常轻量高效的实现当前需求,架构如下:
1:线上请求打向nginx后,使用lua完成日志整理:如统一日志格式,过滤无效请求,分组等。
2:根据不同业务的nginx日志,划分不同的topic。
3:lua实现producter异步发送到kafka集群。
4:对不同日志感兴趣的业务组实时消费获取日志数据。
三:相关技术
openresty:
lua-resty-kafka:
四:安装配置
为了简单直接,我们采用单机形式配置部署,集群情况类似。
1)准备openresty依赖:
apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl make build-essential
yum install readline-devel pcre-devel openssl-devel gcc
2)安装编译openresty:
#1:安装openresty:
cd /opt/nginx/ # 安装文件所在目录
tar -xzf openresty-1.9.7.4.tar.gz /opt/nginx/
# 指定目录为/opt/openresty,默认在/usr/local。
./configure –prefix=/opt/openresty \
–with-luajit \
–without-http_redis2_module \
–with-http_iconv_module
make install
3)安装lua-resty-kafka
#下载lua-resty-kafka:
unzip lua-resty-kafka-master.zip -d /opt/nginx/
#拷贝lua-resty-kafka到openresty
mkdir /opt/openresty/lualib/kafka
cp -rf /opt/nginx/lua-resty-kafka-master/lib/resty /opt/openresty/lualib/kafka/
4):安装单机kafka
cd /opt/nginx/
tar xvf kafka_2.10-0.9.0.1.tgz
# 开启单机zookeeper
nohup sh bin/zookeeper-server-start.sh config/zookeeper.properties & ./zk.log 2&&1 &
**# 绑定broker ip,必须绑定
**#在config/servier.properties下修改host.name
host.name={your_server_ip}
# 启动kafka服务
nohup sh bin/kafka-server-start.sh config/server.properties & ./server.log 2&&1 &
# 创建测试topic
sh bin/kafka-topics.sh –zookeeper localhost:2181 –create –topic test1 –partitions 1 –replication-factor 1
五:配置运行
开发编辑/opt/openresty/nginx/conf/nginx.conf 实现kafka记录nginx日志功能,源码如下:
worker_processes
worker_connections
default_type
application/octet-
keepalive_timeout
gzip_min_length
gzip_buffers
gzip_http_version 1.1;
gzip_types
text/plain application/x-javascript text/css application/xml application/X-JSON;
charset UTF-8;
# 配置后端代理服务
upstream rc{
server 10.10.*.15:8080 weight=5 max_fails=3;
server 10.10.*.16:8080 weight=5 max_fails=3;
server 10.16.*.54:8080 weight=5 max_fails=3;
server 10.16.*.55:8080 weight=5 max_fails=3;
server 10.10.*.113:8080 weight=5 max_fails=3;
server 10.10.*.137:8080 weight=6 max_fails=3;
server 10.10.*.138:8080 weight=6 max_fails=3;
server 10.10.*.33:8080 weight=4 max_fails=3;
# 最大长连数
keepalive 32;
# 配置lua依赖库地址
lua_package_path “/opt/openresty/lualib/kafka/?.;”;
location /favicon.ico {
index.html index.
location / {
proxy_connect_timeout 8;
proxy_send_timeout 8;
proxy_read_timeout 8;
proxy_buffer_size 4k;
proxy_buffers 512 8k;
proxy_busy_buffers_size 8k;
proxy_temp_file_write_size 64k;
proxy_next_upstream http_500 http_502
http_503 http_504
error timeout invalid_
index.html index.
proxy_pass http://
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_
# 使用log_by_lua 包含lua代码,因为log_by_lua指令运行在请求最后且不影响proxy_pass机制
log_by_lua '
-- 引入lua所有api
local cjson = require "cjson"
local producer = require "resty.kafka.producer"
-- 定义kafka broker地址,ip需要和kafka的host.name配置一致
local broker_list = {
{ host = "10.10.78.52", port = 9092 },
-- 定义json便于日志数据整理收集
local log_json = {}
log_json["uri"]=ngx.var.uri
log_json["args"]=ngx.var.args
log_json["host"]=ngx.var.host
log_json["request_body"]=ngx.var.request_body
log_json["remote_addr"] = ngx.var.remote_addr
log_json["remote_user"] = ngx.var.remote_user
log_json["time_local"] = ngx.var.time_local
log_json["status"] = ngx.var.status
log_json["body_bytes_sent"] = ngx.var.body_bytes_sent
log_json["http_referer"] = ngx.var.http_referer
log_json["http_user_agent"] = ngx.var.http_user_agent
log_json["http_x_forwarded_for"] = ngx.var.http_x_forwarded_for
log_json["upstream_response_time"] = ngx.var.upstream_response_time
log_json["request_time"] = ngx.var.request_time
-- 转换json为字符串
local message = cjson.encode(log_json);
-- 定义kafka异步生产者
local bp = producer:new(broker_list, { producer_type = "async" })
-- 发送日志消息,send第二个参数key,用于kafka路由控制:
-- key为nill(空)时,一段时间向同一partition写入数据
-- 指定key,按照key的hash写入到对应的partition
local ok, err = bp:send("test1", nil, message)
if not ok then
ngx.log(ngx.ERR, "kafka send err:", err)
error_page
500 502 503 504
location = /50x.html {
六:检测&运行
检测配置,只检测nginx配置是否正确,lua错误日志在nginx的error.log文件中
./nginx -t /opt/openresty/nginx/conf/nginx.conf
./nginx -c /opt/openresty/nginx/conf/nginx.conf
./nginx -s reload
1:使用任意http请求发送给当前nginx,如:
2:查看upstream代理是否工作正常
3:查看kafka 日志对应的topic是否产生消息日志,如下:
# 从头消费topic数据命令
sh kafka-console-consumer.sh –zookeeper 10.10.78.52:2181 –topic test1 –from-beginning
4:ab压力测试
#单nginx+upstream测试:
ab -n 10000 -c 100 -k
Server Software:
Server Hostname:
10.10.34.15
Server Port:
Document Path:
/m/personal/AC8E3BC7-B-A9D6-DF11CB74C3EF/rc/v1?passport=83FBCFFBA1B913E22A0D@qq.sohu.com
Document Length:
13810 bytes
Concurrency Level:
Time taken for tests:
2.148996 seconds
Complete requests:
Failed requests:
(Connect: 0, Length: 9982, Exceptions: 0)
Write errors:
Keep-Alive requests:
Total transferred:
HTML transferred:
Requests per second:
4653.34 [#/sec] (mean)
Time per request:
21.490 [ms] (mean)
Time per request:
0.215 [ms] (mean, across all concurrent requests)
Transfer rate:
[Kbytes/sec] received
Connection Times (ms)
mean[+/-sd] median
Processing:
Percentage of the requests served within a certain time (ms)
701 (longest request)
#单nginx+upstream+log_lua_kafka接入测试:
ab -n 10000 -c 100 -k
Server Software:
openresty/1.9.7.4
Server Hostname:
10.10.78.52
Server Port:
Document Path:
/m/personal/AC8E3BC7-B-A9D6-DF11CB74C3EF/rc/v1?passport=83FBCFFBA1B913E22A0D@qq.sohu.com
Document Length:
34396 bytes
Concurrency Level:
Time taken for tests:
2.234785 seconds
Complete requests:
Failed requests:
(Connect: 0, Length: 9981, Exceptions: 0)
Write errors:
Keep-Alive requests:
Total transferred:
HTML transferred:
Requests per second:
4474.70 [#/sec] (mean)
Time per request:
22.348 [ms] (mean)
Time per request:
0.223 [ms] (mean, across all concurrent requests)
Transfer rate:
[Kbytes/sec] received
Connection Times (ms)
mean[+/-sd] median
Processing:
Percentage of the requests served within a certain time (ms)
1004 (longest request)
作者:u 发表于
https://blog.csdn.net/u/article/details/
阅读:11235 评论:1
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
RabbitMQ和Kafka
转自通九大神的博客
最近公司RabbitMQ的集群出了点问题,然后有些亲就说RabbitMQ慢且不好用,是一个瓶颈,不如换成Kafka。而我本人,使用RabbitMQ有一点久了,认为这个事情应当辩证的去看。所以就在没事的时候简单的看了看RabbitMQ的代码。但是我并没有看太多Kafka的代码,我只简单提下。
根据Kafka官方的文档,Kafka可以被认为一个高大上的集群消息中间件,但是读了下以前一个朋友给的部署文档和Kafka的官方的文档。发现Kafka确实不错,真的可以说是集群消息中间件。
用topic来进行消息管理,每个topic包含多个part,每个part对应一个逻辑log,有多个segment组成。
segment中的消息id由其逻辑位置决定,可以用消息id直接定位到消息的存储位置,避免id到位置的额外映射。
生产者发到某个topic的消息会被均匀的分布到多个part上,broker收到消息会写入最后的segment文件中,当某个segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息消费者才能收到。并且通过rolling的机制,保证segment的文件不至于过大。
消费者可以rewind back到任意位置重新进行消费,当消费者故障时,可以选择最小的offset进行重新读取消费消息。
是不是看起来很爽,但是深入往下看,发现了一些深坑
Kafka对消息的重复、丢失、错误以及顺序型没有严格的要求。但是part只会被consumer group内的一个consumer消费,故kafka保证每个parti内的消息会被顺序的消费。
broker没有副本机制,一旦broker宕机,该broker的消息将都不可用。同时broker是无状态的,broker不保存消费者的状态,由消费者自己保存。无状态导也致消息的删除成为难题,所以Kafka选择消息保存一定时间后会被删除。
大量的依赖Zookeeper,需要Zookeeper来管理broker与consumer的动态加入与离开。以及消费关系及每个partion的消费信息。
看到这里,你如果还明白我说这些深坑是什么意思,那就请带入运维场景和特定故障场景思考下。我稍后会说一下这些坑会带来什么问题。
关于RabbitMQ
RabbitMQ是使用Erlang开发的一个消息队列,可以构建成集群,也可以单独使用。
根据测试,RabbitMQ在不使用ACK机制的,Msg大小为1K的情况下,QPS可达6W+。再双方ACK机制,Msg大小为1K的情况下,QPS瞬间降到了1W+。从某种意义上RabbitMQ还真是慢,但是我们需要思考下。
我们真的每个消息都能到1K吗?
我们真的需要双方都对消息ACK的系统吗?
好了,如果两个回答都是YES,那么RabbitMQ就是慢的。如果是No,那么RabbitMQ还是一个非常快的队列。
RabbitMQ慢有几个原因:
RabbitMQ做为一个Broker,不单单做到了简单的数据转发功能,还保证了单个队列上的数据有序,即便是有多个消费者和多个生产者。
RabbitMQ的策略是实时转发,而不像Kafka那样等待刷盘之后才让消费者来消费。
如果消费者和生产者不对等,会产生大量的磁盘IO操作,进行消息换出。
RabbitMQ为什么不好用:
AMQP协议本身比较复杂,参数比较多。
Erlang写的,很多人不熟悉,并且Mnesia出现问题好多人解决不了。
RabbitMQ和Kafka相比没价值了吗?
很多亲们读到这里,就会想RabbitMQ好像也不怎么样呀。和Kafka相比没什么价值可言了,但是我前面说了一些Kafka的坑,我就在这里面揭示一下。
Kafka大量依赖Zookeeper,它的broker并不保存任何状态,如果Zookeeper集群不幸悲剧了,那么整个Kafka集群的消息就全完蛋了。
上面问题有人会说这概率好小,我也同样认为这个概率很小,那么一个broker当机呢?当一个broker当机了整个消息队列由于负载均衡的算法,在一瞬间消费者和生产者之间的消息就全乱掉了。很多需要保证消息顺序的系统一下子就完蛋了。
这就是RabbitMQ存在的价值和意义,同时RabbitMQ使用了MirrorQueue的机制,也可以做到多个机器进行热备。
RabbitMQ该怎么用
RabbitMQ的消息应当尽可能的小,并且只用来处理实时且要高可靠性的消息。
消费者和生产者的能力尽量对等,否则消息堆积会严重影响RabbitMQ的性能。
集群部署,使用热备,保证消息的可靠性。
Kafka该怎么用
应当有一个非常好的运维监控系统,不单单要监控Kafka本身,还要监控Zookeeper。
对消息顺序不依赖,且不是那么实时的系统。
对消息丢失并不那么敏感的系统。
作者:u 发表于
https://blog.csdn.net/u/article/details/
阅读:4190
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
1首先创建git专用用户 并设置密码
sudo adduser git
passwd git
2 下载gitolite(git用户下)
git clone git://github.com/ossxp-com/gitolite.git
3:还是git用户下
mkdir -p $HOME/bin $HOME/share/gitolite/conf
$HOME/share/gitolite/hooks
// 建立命令,conf,和hooks目录
cd gitolite/src
gl-system-install $HOME/bin $HOME/share/gitolite/conf $HOME/share/gitolite/hooks
把export PATH=/home/git/bin:$PATH写入到bash.rc里
4:修改gitolite/gl-setup
vim gl-setup
把GL_PACKAGE_CONF变量改成上面安装gitolite的配置目录,如:
GL_PACKAGE_CONF=/home/git/bin/gitolite/share/gitolite/conf/
// 否则会打开一个空的~/.gitolite.rc,就不知道该如何往里写配置信息了
5:准备个admin用户
使用 ssh-keygen 生产管理员的公钥密钥对
默认目录在用户根目录下 .ssh/下 (也可以指定目录ssh-keygen -f xxxx)
将公钥 admin.pub copy 进 git 用户下
6:进入git 用户
gl-setup admin.pub (拷贝过来的公钥名字随便起)
会自动打开的.gitolite.rc文件:
修改$GL_PACKAGE_HOOKS,改成gl-system-install指定的hook目录即/home/git/bin/gitolite/share/gitolite/hooks
否则($GL_ADMINDIR(~/.gitolite)/hooks目录中将没有钩子脚本)钩子就不能正确设置, 就失去了gitolite提供给各个仓库的钩子功能
也可以修改gitolite自动建立的仓库根目录的名称$REPO_BASE, 默认是repositories, 也可以改成其他名字,如 repos本文使用默认repositories
但gl-setup执行之后就不要修改该名字
-- .gitolite.rc编辑完成后保存退出,继续自动执行:
出现如下信息就表示成功
create mode 100644 conf/gitolite.conf
添加授权配置文件,包含了gitolite-admin & testing两个库的授权
create mode 100644 keydir/xxx.pub
将gl-setup指定的公钥文件添加到keydir/下面
7:然后进入管理员的用户
git clone :gitolite.git
8 进入clone 出的 gitolite-admin 目录 会有conf 和 keydir 目录
到此git服务器搭建完成可以添加用户了
作者:u 发表于
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
https://blog.csdn.net/u/article/details/
mvn 3.0.4 创建maven项目命令
archetype:generate
-DgroupId=damocles-autocredit -DartifactId=damocles-autocredit
-DarchetypeArtifactId=maven-archetype-quickstart
-DinteractiveMode=false
1 下载源代码:mvn dependency:sources -DdownloadSources=true -DdownloadJavadocs=true
这里主要是在eclipse中使用maven,因此只使用到了一部分命令,整理下来方便以后查阅。
生成清除Eclipse项目结构:
mvn eclipse:eclipse
mvn eclipse:clean
清理(删除target目录下编译内容)
仅打包Web页面文件
mvn war:exploded
mvn compile
mvn package
打包时跳过测试
mvn package -Dmaven.test.skip=ture
还有很多命令目前还没有使用到,以后遇到再补充
本文地址:http://blog.csdn.net/kongxx/article/details/6993501
Maven用了很久了,命令一直记不住,其实想想就那个几个常用的,今天写下来,帮着记忆吧
创建一个简单的Java工程:mvn archetype:create -DgroupId=com.mycompany.example -DartifactId=Example创 建一个java的web工程:mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mycompany.app -DartifactId=my-webapp打包:mvn package编译:mvn compile编译测试程序:mvn test-compile清空:mvn clean运行测试:mvn test生成站点目录: mvn site生成站点目录并发布:mvn site-deploy安装当前工程的输出文件到本地仓库: mvn install安 装指定文件到本地仓库:mvn install:install-file -DgroupId=&groupId& -DartifactId=&artifactId& -Dversion=1.0.0 -Dpackaging=jar -Dfile=&myfile.jar&查看实际pom信息: mvn help:effective-pom分析项目的依赖信息:mvn dependency:analyze 或 mvn dependency:tree跳过测试运行maven任务:
mvn -Dmaven.test.skip=true XXX生成eclipse项目文件: mvn eclipse:eclipse查看帮助信息:mvn help:help 或 mvn help:help -Ddetail=true查看插件的帮助信息:mvn &plug-in&:help,比如:mvn dependency:help 或 mvn ant:help 等等。
1. 创建Maven的普通java项目:
mvn archetype:create
-DgroupId=packageName
-DartifactId=projectName
2. 创建Maven的Web项目:
mvn archetype:create
-DgroupId=packageName
-DartifactId=webappName
-DarchetypeArtifactId=maven-archetype-webapp
3. 编译源代码: mvn compile
4. 编译测试代码:mvn test-compile
5. 运行测试:mvn test
6. 产生site:mvn site
7. 打包:mvn package
8. 在本地Repository中安装jar:mvn install
9. 清除产生的项目:mvn clean
10. 生成eclipse项目:mvn eclipse:eclipse
11. 生成idea项目:mvn idea:idea
12. 组合使用goal命令,如只打包不测试:mvn -Dtest package
13. 编译测试的内容:mvn test-compile
14. 只打jar包: mvn jar:jar
15. 只测试而不编译,也不测试编译:mvn test -skipping compile -skipping test-compile
( -skipping 的灵活运用,当然也可以用于其他组合命令)
16. 清除eclipse的一些系统设置:mvn eclipse:clean
http://cloudera.iteye.com/blog/424795
博客分类:
java编写的用于构建系统的自动化工具。
目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本。
,官方简易入门文档;
,官方入门文档;
,官方的cookbook;
,POM文件的设置参考
,settings文件的设置参考
,免费的电子书,下载需要注册。
Maven正在逐渐取代Ant,很多java开源软件(Spring、Struts2 ……)已经使用maven。
不需要写复杂的处理脚本;声明式的类库依赖管理。
构建:比如生成class、jar、war或者ear文件生成文档:比如生成javadoc、网站文档生成报告:比如junit测试报告生成依赖类库:生成文档,说明项目多其他软件的依赖有关SCM:SCM(Software Configuration Management),软件配置管理,比如版本控制,比如bug管理等等发布:生成供发布的分发包,比如生成Struts2的分发包,供提交给用户使用部署:比如,web应用程序,自动部署到指定的服务器上通过,演示结合maven和svn的功能。
从官方网站下载最新的Maven分发包,当前为2.0.9;
解压缩到本地;配置maven, 将maven/bin目录设置到windows环境变量Path中检查maven是否安装成功, 在命令行中执行
mvn -version
Maven的基本使用介绍通过命令行编写简单的java和web项目。
通过maven在命令行下创建普通java项目,也就是main方法执行的项目或者jar文件的类库。
mvn archetype:generate
在交互界面中:
Choose a number: 回车即可,也就是选择15Define value for groupId: 输入组织id,比如easymorse.comDefine value for artifactId:输入项目名称,比如helloworldDefine value for version: 输入版本号,可以直接回车,默认是1.0-SNAPSHOTDefine value for package: java的包名,比如com.easymorse然后回车表示确认上述输入即可。观察helloworld目录(Define value for artifactId输入的项目名称)下生成的文件和目录:
项目构建文件: pom.xml代码框架: src\main\java\com\easymorse\App.java
测试代码: src\test\java\com\easymorse\.java
命令行进入helloworld目录Define value for artifactId输入的项目名称)。
mvn package
检查命令生成了什么?
target目录编译了代码编译了测试代码使用junit测试并生成的报告生成代码的jar文件运行打包的jar文件:
target\helloworld-1.0-SNAPSHOT.jar com.easymorse.App
编译源程序
mvn compile
编译并测试
清空生成的文件
将maven项目转化为eclipse项目
命令行运行:
mvn eclipse:eclipse
打开eclipse,菜单选择:file&import&general&existing projects into workspace,在对话框中选中目录,导入即可。
如果要清除有关eclipse项目的配置信息:
mvn -Dwtpversion=1.0 eclipse:clean
mvn eclipse:clean clean
通过maven在命令行下创建java web项目。
在命令行输入,这一步和创建java项目类似:
mvn archetype:generate
交互步骤说明:
Choose a number: 回车即可,也就是选择18,这里和java普通项目不一样Define value for groupId: 输入组织id,比如easymorse.comDefine value for artifactId:输入项目名称,比如helloworldDefine value for version: 输入版本号,可以直接回车,默认是1.0-SNAPSHOTDefine value for package: java的包名,比如com.easymorse然后回车表示确认上述输入即可。需要在pom.xml文件中增加servlet容器的插件:
&groupId&org.codehaus.mojo&/groupId&
&artifactId&tomcat-maven-plugin&/artifactId&
&groupId&org.mortbay.jetty&/groupId&
&artifactId&maven-jetty-plugin&/artifactId&
&version&6.1.6&/version&
&artifactId&maven-compiler-plugin&/artifactId&
&config}

我要回帖

更多关于 最高维空间 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信