Friday, July 31, 2015

一次非常有意思的 SQL 优化经历

场景

我用的数据库是mysql5.6,下面简单的介绍下场景。
文/风过无痕-唐
课程表
SQL优化 数据库优化
create table Course(

c_id int PRIMARY KEY,

name varchar(10)

)
SQL优化 数据库优化
数据100条
学生表:
SQL优化 数据库优化
create table Student(

id int PRIMARY KEY,name varchar(10)
)
SQL优化 数据库优化
数据70000条
学生成绩表SC
SQL优化 数据库优化
CREATE table SC(
    sc_id int PRIMARY KEY,
    s_id int,
    c_id int,
    score int
)
SQL优化 数据库优化
数据70w条
查询目的:
查找语文考100分的考生
查询语句:
select s.* from Student s 
where s.s_id in (select s_id from SC sc where sc.c_id = 0 and sc.score = 100 )
执行时间:30248.271s
晕,为什么这么慢,先来查看下查询计划:
EXPLAIN select s.* from Student s where s.s_id in (select s_id from SC sc where sc.c_id = 0 and sc.score = 100 )
SQL优化 数据库优化
发现没有用到索引,type全是ALL,那么首先想到的就是建立一个索引,建立索引的字段当然是在where条件的字段。
先给sc表的c_id和score建个索引
CREATE index sc_c_id_index on SC(c_id);
CREATE index sc_score_index on SC(score);
再次执行上述查询语句,时间为: 1.054s
快了3w多倍,大大缩短了查询时间,看来索引能极大程度的提高查询效率,建索引很有必要,很多时候都忘记建
索引了,数据量小的的时候压根没感觉,这优化的感觉挺爽。
但是1s的时间还是太长了,还能进行优化吗,仔细看执行计划:
SQL优化 数据库优化
查看优化后的sql:
SQL优化 数据库优化
SELECT
    `YSB`.`s`.`s_id` AS `s_id`, 
   `YSB`.`s`.`name` AS `name`

FROM
    `YSB`.`Student` `s`
WHERE
    < in_optimizer > (
        `YSB`.`s`.`s_id` ,< EXISTS > (
            SELECT
                1
            FROM
                `YSB`.`SC` `sc`
            WHERE
                (
                    (`YSB`.`sc`.`c_id` = 0)
                    AND (`YSB`.`sc`.`score` = 100)
                    AND (
                        < CACHE > (`YSB`.`s`.`s_id`) = `YSB`.`sc`.`s_id`
                    )
                )
        )
    )
SQL优化 数据库优化
补充:这里有网友问怎么查看优化后的语句
方法如下:
在命令窗口执行 SQL优化 数据库优化
SQL优化 数据库优化
有type=all
按照我之前的想法,该sql的执行的顺序应该是先执行子查询
select s_id from SC sc where sc.c_id = 0 and sc.score = 100
耗时:0.001s
得到如下结果:
SQL优化 数据库优化
然后再执行
select s.* from Student s where s.s_id in(7,29,5000)
耗时:0.001s
这样就是相当快了啊,Mysql竟然不是先执行里层的查询,而是将sql优化成了exists子句,并出现了EPENDENT SUBQUERY,
mysql是先执行外层查询,再执行里层的查询,这样就要循环70007*8次。
那么改用连接查询呢?
SQL优化 数据库优化
SELECT s.* from 

Student s

INNER JOIN SC sc

on sc.s_id = s.s_id

where sc.c_id=0 and sc.score=100
SQL优化 数据库优化
这里为了重新分析连接查询的情况,先暂时删除索引sc_c_id_index,sc_score_index
执行时间是:0.057s
效率有所提高,看看执行计划:
SQL优化 数据库优化
这里有连表的情况出现,我猜想是不是要给sc表的s_id建立个索引
CREATE index sc_s_id_index on SC(s_id);
show index from SC
SQL优化 数据库优化
在执行连接查询
时间: 1.076s,竟然时间还变长了,什么原因?查看执行计划:
SQL优化 数据库优化
优化后的查询语句为:
SQL优化 数据库优化
SELECT
    `YSB`.`s`.`s_id` AS `s_id`,
    `YSB`.`s`.`name` AS `name`FROM
    `YSB`.`Student` `s`
JOIN `YSB`.`SC` `sc`
WHERE
    (
        (
            `YSB`.`sc`.`s_id` = `YSB`.`s`.`s_id`
        )
        AND (`YSB`.`sc`.`score` = 100)
        AND (`YSB`.`sc`.`c_id` = 0)
    )
SQL优化 数据库优化
貌似是先做的连接查询,再进行的where条件过滤
回到前面的执行计划:
SQL优化 数据库优化
这里是先做的where条件过滤,再做连表,执行计划还不是固定的,那么我们先看下标准的sql执行顺序:
SQL优化 数据库优化
正常情况下是先join再进行where过滤,但是我们这里的情况,如果先join,将会有70w条数据发送join做操,因此先执行where


过滤是明智方案,现在为了排除mysql的查询优化,我自己写一条优化后的sql
SQL优化 数据库优化
SELECT
    s.*
FROM
    (
        SELECT
            *
        FROM
            SC sc
        WHERE
            sc.c_id = 0
        AND sc.score = 100
    ) t
INNER JOIN Student s ON t.s_id = s.s_id
SQL优化 数据库优化
即先执行sc表的过滤,再进行表连接,执行时间为:0.054s
和之前没有建s_id索引的时间差不多
查看执行计划:
SQL优化 数据库优化
先提取sc再连表,这样效率就高多了,现在的问题是提取sc的时候出现了扫描表,那么现在可以明确需要建立相关索引
CREATE index sc_c_id_index on SC(c_id);
CREATE index sc_score_index on SC(score);
再执行查询:
SQL优化 数据库优化
SELECT
    s.*
FROM
    (
        SELECT
            *
        FROM
            SC sc
        WHERE
            sc.c_id = 0
        AND sc.score = 100
    ) t

INNER JOIN Student s ON t.s_id = s.s_id
SQL优化 数据库优化
执行时间为:0.001s,这个时间相当靠谱,快了50倍
执行计划:
SQL优化 数据库优化
我们会看到,先提取sc,再连表,都用到了索引。
那么再来执行下sql
SQL优化 数据库优化
SELECT s.* 

from Student s

INNER JOIN SC sc

on sc.s_id = s.s_id

where sc.c_id=0 and sc.score=100
SQL优化 数据库优化
执行时间0.001s
执行计划:
SQL优化 数据库优化
这里是mysql进行了查询语句优化,先执行了where过滤,再执行连接操作,且都用到了索引。

2015-04-30日补充:最近又重新导入一些生产数据,经测试发现,前几天优化完的sql执行效率又变低了
调整内容为SC表的数据增长到300W,学生分数更为离散。
先回顾下:
show index from SC
SQL优化 数据库优化
执行sql
SQL优化 数据库优化
SELECT s.* from 

Student s

INNER JOIN SC sc

on sc.s_id = s.s_id

where sc.c_id=81 and sc.score=84
SQL优化 数据库优化
执行时间:0.061s,这个时间稍微慢了点
执行计划:
SQL优化 数据库优化
这里用到了intersect并集操作,即两个索引同时检索的结果再求并集,再看字段score和c_id的区分度,
单从一个字段看,区分度都不是很大,从SC表检索,c_id=81检索的结果是70001,score=84的结果是39425
而c_id=81 and score=84 的结果是897,即这两个字段联合起来的区分度是比较高的,因此建立联合索引查询效率
将会更高,从另外一个角度看,该表的数据是300w,以后会更多,就索引存储而言,都是不小的数目,随着数据量的
增加,索引就不能全部加载到内存,而是要从磁盘去读取,这样索引的个数越多,读磁盘的开销就越大,因此根据具体
业务情况建立多列的联合索引是必要的,那么我们来试试吧。
alter table SC drop index sc_c_id_index;
alter table SC drop index sc_score_index;
create index sc_c_id_score_index on SC(c_id,score);
执行上述查询语句,消耗时间为:0.007s,这个速度还是可以接收的
执行计划:
SQL优化 数据库优化
该语句的优化暂时告一段落
总结:
1.mysql嵌套子查询效率确实比较低
2.可以将其优化成连接查询
3.连接表时,可以先用where条件对表进行过滤,然后做表连接
(虽然mysql会对连表语句做优化)
4.建立合适的索引,必要时建立多列联合索引
5.学会分析sql执行计划,mysql会对sql进行优化,所以分析执行计划很重要

索引优化

上面讲到子查询的优化,以及如何建立索引,而且在多个字段索引时,分别对字段建立了单个索引
后面发现其实建立联合索引效率会更高,尤其是在数据量较大,单个列区分度不高的情况下。

单列索引

查询语句如下:
select * from user_test_copy where sex = 2 and type = 2 and age = 10
索引:
CREATE index user_test_index_sex on user_test_copy(sex);
CREATE index user_test_index_type on user_test_copy(type);

CREATE index user_test_index_age on user_test_copy(age);
分别对sex,type,age字段做了索引,数据量为300w,查询时间:0.415s
执行计划:
SQL优化 数据库优化
发现type=index_merge
这是mysql对多个单列索引的优化,对结果集采用intersect并集操作

多列索引

我们可以在这3个列上建立多列索引,将表copy一份以便做测试
create index user_test_index_sex_type_age on user_test(sex,type,age);
查询语句:
select * from user_test where sex = 2 and type = 2 and age = 10
执行时间:0.032s,快了10多倍,且多列索引的区分度越高,提高的速度也越多
执行计划:
SQL优化 数据库优化
最左前缀
多列索引还有最左前缀的特性:
执行一下语句:
select * from user_test where sex = 2
select * from user_test where sex = 2 and type = 2
select * from user_test where sex = 2 and age = 10
都会使用到索引,即索引的第一个字段sex要出现在where条件中

索引覆盖

就是查询的列都建立了索引,这样在获取结果集的时候不用再去磁盘获取其它列的数据,直接返回索引数据即可
如:
select sex,type,age from user_test where sex = 2 and type = 2 and age = 10
执行时间:0.003s
要比取所有字段快的多

排序

select * from user_test where sex = 2 and type = 2 ORDER BY user_name
时间:0.139s
在排序字段上建立索引会提高排序的效率
create index user_name_index on user_test(user_name)
最后附上一些sql调优的总结,以后有时间再深入研究
1. 列类型尽量定义成数值类型,且长度尽可能短,如主键和外键,类型字段等等
2. 建立单列索引
3. 根据需要建立多列联合索引
当单个列过滤之后还有很多数据,那么索引的效率将会比较低,即列的区分度较低,
那么如果在多个列上建立索引,那么多个列的区分度就大多了,将会有显著的效率提高。
4. 根据业务场景建立覆盖索引
只查询业务需要的字段,如果这些字段被索引覆盖,将极大的提高查询效率
5. 多表连接的字段上需要建立索引
这样可以极大的提高表连接的效率
6. where条件字段上需要建立索引
7. 排序字段上需要建立索引
8. 分组字段上需要建立索引
9. Where条件上不要使用运算函数,以免索引失效

From:
http://www.chinaz.com/web/2015/0505/403573_2.shtml

大型Windows平台网站图片服务器架构的演进

http://www.chinaz.com/web/2015/0731/429088.shtml

构建在Windows平台之上的网站,往往会被业内众多架构师认为很“保守”。很大部分原因,是由于微软技术体系的封闭和部分技术人员的短视造成的。由于长期缺乏开源支持,所以只能“闭门造车”,这样很容易形成思维局限性和短板。就拿图片服务器为例子,如果前期没有容量规划和可扩展的设计,那么随着图片文件的不断增多和访问量的上升,由于在性能、容错/容灾、扩展性等方面的设计不足,后续将会给开发、运维工作带来很多问题,严重时甚至会影响到网站业务正常运作和互联网公司的发展(这绝不是在危言耸听)。
之所以选择Windows平台来构建网站和图片服务器,很大部分由创始团队的技术背景决定的,早期的技术人员可能更熟悉.NET,或者负责人认为Windows/.NET的易用性、“短平快”的开发模式、人才成本等方面都比较符合创业初期的团队,自然就选择了Windows。后期业务发展到一定规模,也很难轻易将整体架构迁移到其它平台上了。当然,对于构建大规模互联网,更建议首选开源架构,因为有很多成熟的案例和开源生态的支持,避免重复造轮子和支出授权费用。对于迁移难度较大的应用,比较推荐Linux、Mono、Mysql、Memcahed……混搭的架构,同样能支撑高并发访问和大数据量。
单机时代的图片服务器架构(集中式)
初创时期由于时间紧迫,开发人员水平也很有限等原因。所以通常就直接在website文件所在的目录下,建立1个upload子目录,用于保存用户上传的图片文件。如果按业务再细分,可以在upload目录下再建立不同的子目录来区分。例如:upload\QA,upload\Face等。
在数据库表中保存的也是”upload/qa/test.jpg”这类相对路径。
用户的访问方式如下:
http://upload.chinaz.com/2015/0731/1438326331263.jpg
程序上传和写入方式:
程序员A通过在web.config中配置物理目录D:\Web\yourdomain\upload 然后通过stream的方式写入文件;
程序员B通过Server.MapPath等方式,根据相对路径获取物理目录 然后也通过stream的方式写入文件。
优点:实现起来最简单,无需任何复杂技术,就能成功将用户上传的文件写入指定目录。保存数据库记录和访问起来倒是也很方便。
缺点:上传方式混乱,严重不利于网站的扩展。
针对上述最原始的架构,主要面临着如下问题:
  1. 随着upload目录中文件越来越多,所在分区(例如D盘)如果出现容量不足,则很难扩容。只能停机后更换更大容量的存储设备,再将旧数据导入。
  2. 在部署新版本(部署新版本前通过需要备份)和日常备份website文件的时候,需要同时操作upload目录中的文件,如果考虑到访问量上升,后边部署由多台Web服务器组成的负载均衡集群,集群节点之间如果做好文件实时同步将是个难题。
集群时代的图片服务器架构(实时同步)
在website站点下面,新建一个名为upload的虚拟目录,由于虚拟目录的灵活性,能在一定程度上取代物理目录,并兼容原有的图片上传和访问方式。用户的访问方式依然是:
http://upload.chinaz.com/2015/0731/1438326331844.jpg
优点:配置更加灵活,也能兼容老版本的上传和访问方式。
因为虚拟目录,可以指向本地任意盘符下的任意目录。这样一来,还可以通过接入外置存储,来进行单机的容量扩展。
缺点:部署成由多台Web服务器组成的集群,各个Web服务器(集群节点)之间(虚拟目录下的)需要实时的去同步文件,由于同步效率和实时性的限制,很难保证某一时刻各节点上文件是完全一致的。
基本架构如下图所示:
网站图片优化 网站优化 CDN服务 Web优化 站内优化
从上图可看出,整个Web服务器架构已经具备“可扩展、高可用”了,主要问题和瓶颈都集中在多台服务器之间的文件同步上。
上述架构中只能在这几台Web服务器上互相“增量同步”,这样一来,就不支持文件的“删除、更新”操作的同步了。
早期的想法是,在应用程序层面做控制,当用户请求在web1服务器进行上传写入的同时,也同步去调用其它web服务器上的上传接口,这显然是得不偿失的。所以我们选择使用Rsync类的软件来做定时文件同步的,从而省去了“重复造轮子”的成本,也降低了风险性。
同步操作里面,一般有比较经典的两种模型,即推拉模型:所谓“拉”,就是指轮询地去获取更新,所谓推,就是发生更改后主动的“推”给其它机器。当然,也可以采用加高级的事件通知机制来完成此类动作。
在高并发写入的场景中,同步都会出现效率和实时性问题,而且大量文件同步也是很消耗系统和带宽资源的(跨网段则更明显)。
注:相关网站建设技巧阅读请移步到建站教程频道。

集群时代的图片服务器架构改进(共享存储)
沿用虚拟目录的方式,通过UNC(网络路径)的方式实现共享存储(将upload虚拟目录指向UNC)
用户的访问方式1:
http://upload.chinaz.com/2015/0731/1438326331693.jpg
用户的访问方式2(可以配置独立域名):
http://upload.chinaz.com//
支持UNC所在server上配置独立域名指向,并配置轻量级的web服务器,来实现独立图片服务器。
优点: 通过UNC(网络路径)的方式来进行读写操作,可以避免多服务器之间同步相关的问题。相对来讲很灵活,也支持扩容/扩展。支持配置成独立图片服务器和域名访问,也完整兼容旧版本的访问规则。
缺点 :但是UNC配置有些繁琐,而且会造成一定的(读写和安全)性能损失。可能会出现“单点故障”。如果存储级别没有raid或者更高级的灾备措施,还会造成数据丢失。
基本架构如下图所示:
网站图片优化 网站优化 CDN服务 Web优化 站内优化
在早期的很多基于Linux开源架构的网站中,如果不想同步图片,可能会利用NFS来实现。事实证明,NFS在高并发读写和海量存储方面,效率上存在一定问题,并非最佳的选择,所以大部分互联网公司都不会使用NFS来实现此类应用。当然,也可以通过Windows自带的DFS来实现,缺点是“配置复杂,效率未知,而且缺乏资料大量的实际案例”。另外,也有一些公司采用FTP或Samba来实现。
上面提到的几种架构,在上传/下载操作时,都经过了Web服务器(虽然共享存储的这种架构,也可以配置独立域名和站点来提供图片访问,但上传写入仍然得经过Web服务器上的应用程序来处理),这对Web服务器来讲无疑是造成巨大的压力。所以,更建议使用独立的图片服务器和独立的域名,来提供用户图片的上传和访问。
独立图片服务器/独立域名的好处
  • 图片访问是很消耗服务器资源的(因为会涉及到操作系统的上下文切换和磁盘I/O操作)。
  • 分离出来后,Web/App服务器可以更专注发挥动态处理的能力。
  • 独立存储,更方便做扩容、容灾和数据迁移。
  • 浏览器(相同域名下的)并发策略限制,性能损失。 访问图片时,请求信息中总带cookie信息,也会造成性能损失。
  • 方便做图片访问请求的负载均衡,方便应用各种缓存策略(HTTP Header、Proxy Cache等),也更加方便迁移到CDN。
......
我们可以使用Lighttpd或者Nginx等轻量级的web服务器来架构独立图片服务器。

当前的图片服务器架构(分布式文件系统+CDN)

在构建当前的图片服务器架构之前,可以先彻底撇开web服务器,直接配置单独的图片服务器/域名。但面临如下的问题:
  1. 旧图片数据怎么办?能否继续兼容旧图片路径访问规则?
  2. 独立的图片服务器上需要提供单独的上传写入的接口(服务API对外发布),安全问题如何保证?
  3. 同理,假如有多台独立图片服务器,是使用可扩展的共享存储方案,还是采用实时同步机制?
直到应用级别的(非系统级) DFS(例如FastDFS HDFS MogileFs MooseFS、TFS)的流行,简化了这个问题:执行冗余备份、支持自动同步、支持线性扩展、支持主流语言的客户端api上传/下载/删除等操作,部分支持文件索引,部分支持提供Web的方式来访问。
考虑到各DFS的特点,客户端API语言支持情况(需要支持C#),文档和案例,以及社区的支持度,我们最终选择了FastDFS来部署。
唯一的问题是:可能会不兼容旧版本的访问规则。如果将旧图片一次性导入FastDFS,但由于旧图片访问路径分布存储在不同业务数据库的各个表中,整体更新起来也十分困难,所以必须得兼容旧版本的访问规则。架构升级往往比做全新架构更有难度,就是因为还要兼容之前版本的问题。(给飞机在空中换引擎可比造架飞机难得多)
解决方案如下:
首先,关闭旧版本上传入口(避免继续使用导致数据不一致)。将旧图片数据通过rsync工具一次性迁移到独立的图片服务器上(即下图中描述的Old Image Server)。在最前端(七层代理,如Haproxy、Nginx)用ACL(访问规则控制),将旧图片对应URL规则的请求(正则)匹配到,然后将请求直接转发指定的web 服务器列表,在该列表中的服务器上配置好提供图片(以Web方式)访问的站点,并加入缓存策略。这样实现旧图片服务器的分离和缓存,兼容了旧图片的访问规则并提升旧图片访问效率,也避免了实时同步所带来的问题。

整体架构如图:
网站图片优化 网站优化 CDN服务 Web优化 站内优化
基于FastDFS的独立图片服务器集群架构,虽然已经非常的成熟,但是由于国内“南北互联”和IDC带宽成本等问题(图片是非常消耗流量的),我们最终还是选择了商用的CDN技术,实现起来也非常容易,原理其实也很简单,我这里只做个简单的介绍:
将img域名cname到CDN厂商指定的域名上,用户请求访问图片时,则由CDN厂商提供智能DNS解析,将最近的(当然也可能有其它更复杂的策略,例如负载情况、健康状态等)服务节点地址返回给用户,用户请求到达指定的服务器节点上,该节点上提供了类似Squid/Vanish的代理缓存服务,如果是第一次请求该路径,则会从源站获取图片资源返回客户端浏览器,如果缓存中存在,则直接从缓存中获取并返回给客户端浏览器,完成请求/响应过程。
由于采用了商用CDN服务,所以我们并没有考虑用Squid/Vanish来重复构建前置代理缓存。
上面的整个集群架构,可以很方便的做横向扩展,能满足一般垂直领域大型网站的图片服务需求(当然,像taobao这样超大规模的可能另当别论)。经测试,提供图片访问的单台Nginx服务器(至强E5四核CPU、16G内存、SSD),对小静态页面(压缩后的)可以扛住上万的并发且毫无压力。当然,由于图片本身体积比纯文本的静态页面大很多,提供图片访问的服务器的抗并发能力,往往会受限于磁盘的I/O处理能力和IDC提供的带宽。Nginx的抗并发能力还是非常强的,而且对资源占用很低,尤其是处理静态资源,似乎都不需要有过多担心了。可以根据实际访问量的需求,通过调整Nginx参数,Linux内核调优、缓存策略等手段做更大程度的优化,也可以通过增加服务器或者升级服务器配置来做扩展,最直接的是通过购买更高级的存储设备和更大的带宽,以满足更大访问量的需求。
值得一提的是,在“云计算”流行的当下,也推荐高速发展期间的网站,使用“云存储”这样的方案,既能帮你解决各类存储、扩展、备灾的问题,又能做好CDN加速。最重要的是,价格也不贵。
总结,有关图片服务器架构扩展,大致围绕这些问题展开:
  1. 容量规划和扩展问题。
  2. 数据的同步、冗余和容灾。
  3. 硬件设备的成本和可靠性(是普通机械硬盘,还是SSD,或者更高端的存储设备和方案)。
  4. 文件系统的选择。根据文件特性(例如文件大小、读写比例等)选择是用ext3/4或者NFS/GFS/TFS这些开源的(分布式)文件系统。
  5. 图片的加速访问。采用商用CDN或者自建的代理缓存、web静态缓存架构。
  6. 旧图片路径和访问规则的兼容性,应用程序层面的可扩展,上传和访问的性能和安全性等。
作者介绍
丁浪,技术架构师。擅长大规模(高并发、高可用、海量数据)互联网架构,专注于打造“高性能,可扩展/伸缩,稳定,安全”的技术架构。 热衷于技术研究和分享,曾分享和独立撰写过大量技术文章。

Sunday, July 26, 2015

极客DIY:轻松使用树莓派控制灯

 

最近笔者正在研究微控制器和基于物联网的设备安全。因此,我开始考虑建立一个小型家庭系统化系统,虽然目前还没完成,但我想先在文章中分享一下我如何使用树莓派2及一些其他电子元件来控制房间的灯光。当然,我在这里不会介绍树莓派的初始设置,因为你可以在网上发现各种各样的教程。

注意事项

在我们继续实验之前,我想有必要提醒一下关于实验中“电流”的危险性。一旦出现任何状况,最糟糕的情况就是死掉或者烧了你的房子。所以,请不要试图完成任何文中提到但是你不理解事情,或者你可以在制作的时候寻求一些有经验的电工的帮助。

好啦,让我们开始DIY吧!

实验准备

硬件需求

1、树莓派2(或者任何5V输出功率的型号,均可)

2、USB无线软件狗

3、8路继电器

4、一些Female-Female跳线(40 PCS FEMALE TO FEMALE JUMPER WIRES)

5、灯头电线

(以上硬件,某宝均有销售)

其他要求

1、了解基本Python语言或者其他任何语言(我会用到Python)

2、对Linux系统有基本了解

3、专心致志

流程要求

首先,用ssh链接到树莓派上,并安装“apache”和“php5”:
 
你会需要安装python的GPIO库来控制树莓派的GPIO插脚:
 
了解元件

现在,在我们继续制作之前,你需要了解一下我们将使用到的电子元件。

1、继电器

继电器是一种使用非常低的电压输入控制高压电的电气设备。由一个线圈缠绕的金属杆和两个小型金属节点构成的闭合电路。其中一个节点是固定的,其他的都是可移动的。无论何时,当电流通过线圈的时候,它会产生一个磁场,吸引可移动节点向静态节点运动,形成电路。通过给线圈供应小额电压,我们就能完成高压电路的轮回。同时,静态节点并非在物理上与线圈有联系,因此一旦有地方出错,微控制器驱动的线圈也很少出现故障。
 

试验中,我使用一个8路继电器,可以同时控制8个设备。你可以选择自己的继电器或者继电板,但是请确保你在继电器的额定电压之内处理,以避免任何事故的发生。

2、跳线

跳线就是我们链接树莓派GPIO插脚与继电器的简单连接电线。

3、树莓派2

我们使用树莓派2作为一个微控制器来操纵继电器。它有40个GPIO(通用输入/输出)插脚。你可以看到下面这些插脚的布局,我们将使用这些接口为继电器加电和控制开关。
 

连接电路

电路非常简单。我们将连接GPIO插脚到继电板上。首先连接继电器板上的“GND”与树莓派上的任意“GND”。然后链接继电器的“IND1”到GPIO PIN 17,我们会把GPIO PIN 17作为一个控制第一继电器的输出。最后,将继电器的“VCC”连接到树莓派的“5V”GPIO插脚。让我们简单直接设置一下:
 

现在我们到了最为棘手的部分,我们要将继电器连接到接通主电路供电的灯头上。但是,我想先给你介绍一个如何通过直流屏电源开启及关闭灯光的简单操作。

我们通常连接两根电线到灯泡上,来提供电流供给。其中一根电线是“中性”电线,另一根则是实际带着电流的“负极”电线,同样的这里也有一个控制整个电路的开关。因此,当开关(闭合)连接到流经灯泡的电流和负极电线时,电路便完整了。灯泡从而亮了起来。当开关(断开),破坏了电路和灯泡的电流,因此灯泡不亮。这里有一个小的电路图来解释具体情况:
 

当我们在试验中,我们需要“负极电线”通过我们的继电器来打破电路,从而使用继电器开关的控制流经的电流。因此,当继电器打开,在闭合电路中灯泡也应该亮起来,反之亦然。请参考一下完整的电路:
 

控制脚本
现在,终于到了软件的部分。我编写了一个简单的python脚本来控制继电器开关,使用了GPIO PIN 17和一个PHP代码可以在任何移动终端上面来运行python脚本。你可以从我的Github(和CSS)上找到这段代码。
 

 
注意:你将会需要添加“www-data”用户到sudoers文件。

注意+:PHP代码只是为了测试,我们不建议在公共环境中运行。

不久我将完成这个设置,希望回来更新一个新的帖子。请在那时之前,自己动手试一下这个控制灯,但是一定要注意安全。
P.S:本人对于电路经验不是很丰富,因此如果有什么错误或者错过的地方,我会很高兴知道。请各位在评论中不吝赐教,分享你的宝贵意见:) (小编会挑选优秀评论翻译给原文作者)

Thursday, July 23, 2015

How to enable IDP on SRX



If you want to enable IDP on an SRX device, you have to issue certain number of commands which I list step by step from scratch;
1) Install license first if it hasn’t been installed yet. You can see if it is installed or not via “show system license installed” if this command doesn’t give any ouput, get your license from Juniper and follow the steps below. (Bold italic text is my sample license)
oot@srx1> request system license add terminal
[Type ^D at a new line to end input,
 enter blank line between each license key]
JUNOS111111 sdsdsd ssssss sdfsdf sdfsdf sdfsdf sdfsdf
 sdfsdf sdfsdf sdfdsf sdfdsf sdfsdf sdfsdf
 sdfsdf sdfsdf sdfsdf sdfsdf sdfsdf sdfsdf
 sdf
JUNOS111111: successfully added
add license complete (no errors)
2) Check if the server we will fetch IDP files are reachable;
root@srx1> request security idp security-package download check-server
error: fetching for("https://services.netscreen.com/cgi-bin/index.cgi?device=jsrx210&feature=idp&os=10.4&detector=10.4.160100525&from=&to=latest&type=manifest") failed
We can’t reach. Ensure https://services.netscreen.com is reachable i.e hostname is resolvable by SRX and it can establish TCP connections to 443 port of this remote host.
After fixing connectivity issue here is the result;
root@srx1> request security idp security-package download check-server
Successfully retrieved from(https://services.netscreen.com/cgi-bin/index.cgi).
Version info:1996(Detector=11.6.160110809, Templates=1996)

3) Download attack table
root@srx1> request security idp security-package download full-update
Will be processed in async mode. Check the status using the status checking CLI
Check status of the download.
root@srx1> request security idp security-package download status
Done;Successfully downloaded from(https://services.netscreen.com/cgi-bin/index.cgi).
Version info:1996(Tue Sep 20 12:12:23 2011, Detector=11.6.160110809)
It looks great.
4) Install attack table
root@srx1> request security idp security-package install
Will be processed in async mode. Check the status using the status checking CLI
Check status;
root@srx1> request security idp security-package install status
In progress:performing DB update for an xml (SignatureUpdate.xml)
Check once again;
root@srx1> request security idp security-package install status
In progress:Compiling AI signatures ...
Check again;
root@srx1> request security idp security-package install status
Done;Attack DB update : successful - [UpdateNumber=1996,ExportDate=Tue Sep 20 12:12:23 2011,Detector=11.6.160110809]
     Updating control-plane with new detector : successful
     Updating data-plane with new attack or detector : not performed
      due to no existing running policy found.
Heyy, completed!
5) Get policy templates;
root@srx1> request security idp security-package download policy-templates
Will be processed in async mode. Check the status using the status checking CLI
Check status;
root@srx1> request security idp security-package download status
Done;Successfully downloaded from(https://services.netscreen.com/cgi-bin/index.cgi).
Version info:1996
6) Install policy templates
root@srx1> request security idp security-package install policy-templates
Will be processed in async mode. Check the status using the status checking CLI
root@srx1> request security idp security-package install status
Done;policy-templates has been successfully updated into internal repository
     (=>/var/db/scripts/commit/templates.xsl)!
7) Check downloaded files;
root@srx1> start shell
root@srx1% ls /var/db/idpd/sec-download/
SignatureUpdate.xml             libidp-detector.so.tgz.v
applications.xml                platforms.xml
detector-capabilities.xml       sub-download
groups.xml
root@srx1% exit
exit
root@srx1>
8)  Apply templates and commit the configuration to get template policies in CLI
[edit]
root@srx1# set system scripts commit file templates.xsl
[edit]
root@srx1# commit
Then delete templates commit script right after the first commit;
[edit]
root@srx1# delete system scripts commit file templates.xsl
9) Here is the results. Policies are now accessible after which you can set your active policy and start using it or customize it. Enjoy!
root@srx1# set security idp idp-policy ?
Possible completions:
  <policy-name>        IDP policy name
  DMZ_Services         IDP policy name
  DNS_Service          IDP policy name
  File_Server          IDP policy name
  Getting_Started      IDP policy name
  IDP_Default          IDP policy name
  Recommended          IDP policy name
  Web_Server           IDP policy name

2 THOUGHTS ON “HOW TO ENABLE IDP ON SRX

YouTube Channel