MogileFS是一套高效的文件自动备份组件,由Six Apart开发,广泛应用在包括LiveJournal等web2.0站点上。
MogileFS由3个部分组成
   第1个部分:是server端,包括mogilefsd和mogstored两个程序。前者即是mogilefsd的tracker,它将一些全局信息保存在数据库里,例如站点domain,class,host等。后者即是存储节点(store node),它其实是个HTTP Daemon,默认侦听在7500端口,接受客户端的文件备份请求。在安装完后,要运行mogadm工具将所有的store node注册到mogilefsd的数据库里,mogilefsd会对这些节点进行管理和监控。
   第2个部分:是utils(工具集),主要是MogileFS的一些管理工具,例如mogadm等。
   第3个部分:是客户端API,目前只有Perl API(MogileFS.pm)、PHP,用这个模块可以编写客户端程序,实现文件的备份管理功能,提供MogileFS.pm。

当下互联网飞速发展,海量并发所产生的数据量以几何方式增长,随着信息链接方式日益多样化,数据存储的结构也发生了变化,在这样的压力下我们不得不重新审视大量数据的存储所带来了巨大的挑战:
   1、数据采集:对于社交网站一般都是由用户上传的;
   2、数据存储:现在是数据量大爆炸时代,每天都会产生大量的数据,所以数据存储就成了一个大问题;
   3、数据搜索:如果说存储是考验数据的存储能力的话,那搜索就是考量计算机能力了,从大量的数据中搜索出来;
   4、数据共享:数据存储下来之后还要进行数据的共享问题,大量的数据该怎么共享这些数据呢;
   5、数据传输:而海量数据存储下来之后数据怎么用户与用户之间进行安全的传输;
   6、数据分析:数据的分析是了解我们过去的一些行为规范;
   7、数据可视化:而海量数据存储下来之后怎么样可以直观的展示在人们面前呢;

分布式文件系统的几个难点:
   1、缺乏全局时钟、不过同步本身就存在时间差,很难做到步调一致,
   2、面对故障的独立性,分布式是由多个节点组成的,而每个节点都是独立工作的,一个节占故障度不会影响其它节点正常工作,
   3、如何去处理单点故障, 一是:做冗余,对单点做备份;二是:降低单点故障的影响范围
   4、事务类的挑战,在分布环境中怎么处理事务呢;ACID或2PI(两段式提交)、最终一致、BASE法则、CAP理论、Paxos算法;

什么是两段式提交: 
   通过使用某种协议进行通信来完成分布式事务,被称为两段式提交。从名字上看,您可能已经知道有两个阶段:
第一个阶段,即预提交:
   事务协调器给每个事务管理器发送准备操作的信号。
   事务管理器将操作(通常是数据更新)步骤(或细节)写入事务日志。如果失败,事务管理器使用这些步骤重复操作。
   事务管理器本地创建事务并通知资源管理器对资源(例如,数据库或消息服务器)执行操作。
   资源管理器执行操作并向事务管理器报告成功(准备提交信号)或失败(准备回滚)。
   资源管理器等待事务管理器进一步的指令。
   事务管理器向事务协调器报告成功或失败。
第二阶段,即提交阶段:在第二阶段中,第一阶段的结果将传送给所有事务管理器。

如果任何事务管理器报告失败,所有的事务参与者都必须回滚。
   事务协调器让所有事务管理器提交(或回滚)。
   所有事务管理器将提交或回滚信息传递给其资源管理器。
   资源管理器将成功或失败提示返回给事务管理器。
   事务管理器向事务协调器报告成功或失败。

 

CAP理论:一致性,可用性,分区容错性;指一个分布式系统不可以满足一致性,可用性和分区容错性这三个需求,最多只能同时满足其中的两个;
   C(Consistency):一致性,任何一个读操作总是能够读取之前完成的写操作;就是一个数据写入一立马被读到;
   A(Availability):可用性,每一次操作总是能够 在确定的时间返回;无论成功或失败都能收到一个返回值的;
   P(Tolerance of network Partition):分区容错性,在出现网络分区的情况下,仍然能够满足一致性和可用性;

BASE法则模型反ACID模型,完全不同ACID模型,牺牲高一致性,获得可用性或可靠性:
   BA:Basically Available,基本可以用,支持分区失败(sharding碎片划分数据库);
   S:Soft state,软状态,接受一段时间内的状态不同步,异步;
   E:Eventually consistent:最终一致性,弱一致性的表现;
   BASE思想主要强调基本的可用性,如果你需要High 可用性,也就是纯粹的高性能,那么就要以一致性或容错性为牺牲,BASE思想的方案在性能上还是有潜力可挖的。

Paxos算法:比2PC提交更轻量级的分布式事务的协调方式;大概是指不出现故拜占庭将军的前提下,要取得数据的一致性,在通信信道不安全的时候,我们数据传输可能会被人劫持,这样就不能保证数据的可信了,所以必须保证通信信道安全下Paxos算法才可行;

   实现MogileFS的分布式过程,按照下图构建MogileFS分布式文件系统的结构,这里限于机器的原因,一些服务都整合在一起;

   第一步:安装MogileFS软件,我们前面提到,它是由三部分组成,所以三个组件都得安装上,并且每个节点都做MogileFS和Mogstored;

在这里先说一个笔者的基本布局,node0(172.16.27.88)上安装nginx和MariaDB,node1(172.16.27.1)和node2(172.16.27.2)上分别安装了MogileFS和Mogstored,node1和node2都共同使用node0上的MariaDB数据库,nginx做为前端接收用户请求并负载均衡到后端两个节点上;

在node1上的安装和配置过程,修改好配置文件之后复制一份相同的配置文件到node2节点上,因为它们的配置参数都是一样的:

[root@node1 ~]# rpm -ivh perl-MogileFS-Client-1.14-1.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm

[root@node1 ~]# yum -y install MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm MogileFS-Server-2.46-2.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm perl-IO-AIO

# 安装好之后修改配置文件,只需要修改以下几项就可以了

# mysql指使用的数据库是什么,MariaDB也是写mysql;mogdb指数据库名;host=172.16.27.88指定安装数据的地址

[root@node1 ~]# vim /etc/mogilefs/mogilefsd.conf

db_dsn = DBI:mysql:mogdb:host=172.16.27.1
db_user = moguser  # 指登录mogdb数据所使用的用户名

db_pass = linux    # 登录mogdb数据所使用密码

listen = 0.0.0.0:7001  # 0.0.0.0表示监听所有地址

# 再编辑mogstored.conf这个配置文件

maxconns = 10000
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /dfs/mogdata   # 把这项改一个特定的目录,以便存储数据,最好是一个独立分区

[root@node1 ~]# mkdir -pv /dfs/mogdata/dev1  # 创建修改的docroot目录

[root@node1 ~]# chown -R mogilefs.mogilefs /dfs/mogdata/dev1 # 修改属主属组

[root@node1 ~]# chown -R mogilefs.mogilefs /var/run/mogilefsd/

[root@node1 ~]# cd /etc/mogilefs

[root@node1 ~]# scp mogilefsd.conf mogstored.conf root@172.16.27.2:/etc/mogilefs/  # 复制修改好的配置文件到node2的mogilefs目录下,覆盖即可,两个节点都安装配置好之后先不要启动服务,数据库还没有安装

在node2上的安装和配置,这里的配置文件由node1上复制过来就可以了

[root@node2 ~]# rpm -ivh perl-MogileFS-Client-1.14-1.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm

[root@node2 ~]# yum -y install MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm MogileFS-Server-2.46-2.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm perl-IO-AIO

[root@node2 ~]# mkdir -pv /dfs/mogdata/dev2  # 创建修改的docroot目录

[root@node1 ~]# chown -R mogilefs.mogilefs /var/run/mogilefsd/

[root@node2 ~]# chown -R mogilefs.mogilefs /dfs/mogdata/dev2 # 修改属主属组

第二步:安装nginx和MariaDB,这里安装Nginx需要编译安装,因为他需要装载第三方模块才可以使用mogilefs,MariaDB安装这里就不再说明了;

node0节点上的安装步骤:

# 解决依赖关系

[root@node0 ~]# yum -y groupinstall "Development Tools" "Server Platform Development"

[root@node0 ~]# yum -y install openssl-devel pcre-devel

[root@node0 ~]# groupadd -r nginx
[root@node0 ~]# useradd -r -g nginx nginx
[root@node0 ~]# tar xf nginx-1.4.2.tar.gz

[root@node0 ~]# unzip nginx-mogilefs-module-master.zip

[root@node0 ~]# cd nginx-1.4.2
[root@node0 nginx-1.4.2]# ls 
auto  CHANGES  CHANGES.ru  conf configure contrib  html  LICENSE  man  README  src
[root@node0 nginx-1.4.2]# ./configure \
>   --prefix=/usr \
>   --sbin-path=/usr/sbin/nginx \
>   --conf-path=/etc/nginx/nginx.conf \
>   --error-log-path=/var/log/nginx/error.log \
>   --http-log-path=/var/log/nginx/access.log \
>   --pid-path=/var/run/nginx/nginx.pid  \
>   --lock-path=/var/lock/nginx.lock \
>   --user=nginx \
>   --group=nginx \
>   --with-http_ssl_module \
>   --with-http_flv_module \
>   --with-http_stub_status_module \
>   --with-http_gzip_static_module \
>   --http-client-body-temp-path=/var/tmp/nginx/client/ \
>   --http-proxy-temp-path=/var/tmp/nginx/proxy/ \
>   --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
>   --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
>   --http-scgi-temp-path=/var/tmp/nginx/scgi \
>   --with-pcre \
>   --with-debug \
>   --add-module=/root/nginx-mogilefs-module-master  # 这里要指定编译的模块

[root@node0 nginx-1.4.2]# make && make install

# 这里MariaDB安装过程不再说明了,可以参数前面的博文,编译安装好之后就可以可以启动MariaDB和去配置Nginx的相关配置了,还要给nginx提供一个服务脚本;

[root@node0 support-files]# service mysqld start
Starting MySQL...                                          [  OK  ]

[root@node0 nginx-1.4.2]# vim /etc/rc.d/init.d/nginx

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/etc/nginx/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

make_dirs() {
  # make required directories
  user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
  options=`$nginx -V 2>&1 | grep 'configure arguments:'`
  for opt in $options; do
      if [ `echo $opt | grep '.*-temp-path'` ]; then
          value=`echo $opt | cut -d "=" -f 2`
          if [ ! -d "$value" ]; then
              # echo "creating" $value
              mkdir -p $value && chown -R $user $value
          fi
      fi
  done
}

start() {
   [ -x $nginx ] || exit 5
   [ -f $NGINX_CONF_FILE ] || exit 6
   make_dirs
   echo -n $"Starting $prog: "
   daemon $nginx -c $NGINX_CONF_FILE
   retval=$?
   echo
   [ $retval -eq 0 ] && touch $lockfile
   return $retval
}

stop() {
   echo -n $"Stopping $prog: "
   killproc $prog -QUIT
   retval=$?
   echo
   [ $retval -eq 0 ] && rm -f $lockfile
   return $retval
}

restart() {
   configtest || return $?
   stop
   sleep 1
   start
}

reload() {
   configtest || return $?
   echo -n $"Reloading $prog: "
   killproc $nginx -HUP
   RETVAL=$?
   echo
}

force_reload() {
   restart
}

configtest() {
 $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
   status $prog
}

rh_status_q() {
   rh_status >/dev/null 2>&1
}

case "$1" in
   start)
       rh_status_q && exit 0
       $1
       ;;
   stop)
       rh_status_q || exit 0
       $1
       ;;
   restart|configtest)
       $1
       ;;
   reload)
       rh_status_q || exit 7
       $1
       ;;
   force-reload)
       force_reload
       ;;
   status)
       rh_status
       ;;
   condrestart|try-restart)
       rh_status_q || exit 0
           ;;
   *)
       echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
       exit 2
esac

[root@node0 nginx-1.4.2]# chmod +x /etc/init.d/nginx

[root@node0 nginx-1.4.2]# vim /etc/profile.d/nginx.sh

export PATH=/usr/sbin/nginx:$PATH

[root@node0 nginx-1.4.2]# . /etc/profile.d/nginx.sh

[root@node0 nginx-1.4.2]# service nginx start
Starting nginx:                                            [  OK  ]

[root@node0 nginx-1.4.2]# ss -tnl
State      Recv-Q Send-Q        Local Address:Port       Peer Address:Port 
LISTEN     0      128              :::111                     :::*     
LISTEN     0      128               *:111                      *:*     
LISTEN     0      128                *:80                      *:*

测试访问一下nginx的页面:

第三步:连接上数据库,给两个用户授权:

[root@node0 ~]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 46
Server version: 10.0.10-MariaDB-log MariaDB Server

Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> USE mysql;

Database changed

MariaDB [mysql]> GRANT ALL ON *.* TO 'root'@'172.16.%.%' IDENTIFIED BY 'linux';
Query OK, 0 rows affected (0.20 sec)

MariaDB [mysql]> GRANT ALL ON mogdb.* TO 'moguser'@'172.16.%.%' IDENTIFIED BY 'linux';
Query OK, 0 rows affected (0.00 sec)

MariaDB [mysql]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.21 sec)

MariaDB [mysql]> 

第四步:再到两个节点上,在其中一个上设置即可:

[root@node1 mogilefs]# mogdbsetup --dbhost=172.16.27.88 --dbport=3306 --dbname=mogdb --dbrootuser=root --dbrootpass=linux --dbuser=moguser --dbpass=linux --yes

# 可以再回到node0上查看一下生成的数据库

MariaDB [mysql]> USE mogdb;
Database changed

MariaDB [mogdb]> SHOW TABLES;
+----------------------+
| Tables_in_mogdb      |
+----------------------+
| checksum             |
| class                |
| device               |
| domain               |
| file                 |
| file_on              |
| file_on_corrupt      |
| file_to_delete       |
| file_to_delete2      |
| file_to_delete_later |
| file_to_queue        |
| file_to_replicate    |
| fsck_log             |
| host                 |
| server_settings      |
| tempfile             |
| unreachable_fids     |
+----------------------+
17 rows in set (0.03 sec)

第五步:在两个节点的其中一个上添加主机:

[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 host add 172.16.27.1 --ip=172.16.27.1 --status=alive
[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 host add 172.16.27.2 --ip=172.16.27.2 --status=alive
[root@node1 mogilefs]# mogadm --trackers=172.16.27.1:7001 host list
172.16.27.1 [1]: alive
 IP:       172.16.27.1:7500

172.16.27.2 [2]: alive

IP:       172.16.27.2:7500

# 再添加设备

[root@node1 mogilefsd]# mogadm --trackers=172.16.27.1:7001 device add 172.16.27.1 1
[root@node1 mogilefsd]# mogadm --trackers=172.16.27.1:7001 device add 172.16.27.2 2
[root@node1 mogilefsd]# mogadm --trackers=172.16.27.1:7001 device list
172.16.27.1 [1]: alive
                   used(G)    free(G)   total(G)  weight(%)
  dev1:   alive      2.799     15.887     18.686        100

172.16.27.2 [2]: alive
                   used(G)    free(G)   total(G)  weight(%)
  dev2:   alive      1.476     17.210     18.686        100

#

[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 domain add images # 添加域
[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 domain add files
[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 domain add html
[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 domain list  # 查看域

domain               class                mindevcount   replpolicy   hashtype
-------------------- -------------------- ------------- ------------ -------
files                default                   2        MultipleHosts() NONE

html                 default                   2        MultipleHosts() NONE

images               default                   2        MultipleHosts() NONE

[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 class add images class0 --mindevcount=2
[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 class list
domain               class                mindevcount   replpolicy   hashtype
-------------------- -------------------- ------------- ------------ -------
files                default                   2        MultipleHosts() NONE

html                 default                   2        MultipleHosts() NONE

images               class0                    2        MultipleHosts() NONE #添加类
images               default                   2        MultipleHosts() NONE   
# 上传几张图片和测试的页面上去
[root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=images --key='1.png' --file='/usr/share/backgrounds/default_1920x1200.png'                    
[root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=images --key='2.png' --file='/usr/share/backgrounds/wallpaper-six-2560x1240.png'

[root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=images --key='/images/3.png' --file='/usr/share/backgrounds/centos_wallpaper_01_1920x1200.png'

[root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=html --key='/files/index.html' --file='/var/www/html/index.html'
[root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=files --key='/files/index.html' --file='/var/www/html/index.html'

[root@node1 ~]# moglistkeys --trackers=172.16.27.1:7001 --domain=images
/images/3.png
1.png
2.png
[root@node1 ~]# mogfileinfo --trackers=172.16.27.1:7001 --domain=images --key='/images/3.png'
- file: /images/3.png
    class:              default
 devcount:                    2
   domain:               images
      fid:                    5
      key:        /images/3.png
   length:               202652
- http://172.16.27.2:7500/dev2/0/000/000/0000000005.fid
- http://172.16.27.1:7500/dev1/0/000/000/0000000005.fid
[root@node1 ~]# mogfileinfo --trackers=172.16.27.1:7001 --domain=files --key='/files/index.html'
- file: /files/index.html
    class:              default
 devcount:                    2
   domain:                files
      fid:                    9
      key:    /files/index.html
   length:                   53
- http://172.16.27.2:7500/dev2/0/000/000/0000000009.fid
- http://172.16.27.1:7500/dev1/0/000/000/0000000009.fid
[root@node1 ~]#

可以复制这个地址在页面上测试一下,这里是每上传一个文件就都会在两个节点是都存一份,如果节点多的话它会根据定义的devcount自己选择节点存储几份,这样在一个节点掉了也可以在别的节点在有相同的资源可用;

第五步:以上的都配置好了就可以在前端的Nginx上配置访问控制了,修改配置文件:

[root@node0 nginx]# vim nginx.conf

upstream mogcluster {    # 定义多个上游服务器
       server 172.16.27.1:7001;
       server 172.16.27.2:7001;
   }
   server {    # 定义一个虚拟主机
       listen 80;
       server_name www.tanxw.com;

location /images/ {
           mogilefs_tracker mogcluster;
           mogilefs_domain images;

mogilefs_pass {
               proxy_pass $mogilefs_path;
               proxy_hide_header Content-Type;
               proxy_buffering off;
           }
       }
       location ~* ^(/files/.*)$ {
           mogilefs_tracker mogcluster;
           mogilefs_domain files;

mogilefs_pass $1 {
               proxy_pass $mogilefs_path;
               proxy_hide_header Content-Type;
               proxy_buffering off;
           }
       }
   }

# 修改好配置文件后保存退出重启服务

[root@node0 nginx]# service nginx restart
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Stopping nginx:                                            [  OK  ]
Starting nginx:                                            [  OK  ]
[root@node0 nginx]#

然后在页面上测试访问刚才上传的文件以及图片:

总结:

最后还可以测试一下把一个节点掉了,试着访问一下看另外正常工作的节点可不可以正常提供服务,这里还可以添加很多功能的,后续还会更新相关的基础网站服务器架构搭建的文章,在此,如果发现在什么不妥或做得不到的还望大家多提点建议。

本文出自 “温水煮青蛙” 博客,请务必保留此出处http://tanxw.blog.51cto.com/4309543/1409362

分布式文件系统之MogileFS工作原理及实现过程的更多相关文章

  1. 大数据 --> 分布式文件系统HDFS的工作原理

    分布式文件系统HDFS的工作原理 Hadoop分布式文件系统(HDFS)是一种被设计成适合运行在通用硬件上的分布式文件系统.HDFS是一个高度容错性的系统,适合部署在廉价的机器上.它能提供高吞吐量的数 ...

  2. 【转载】Hadoop分布式文件系统HDFS的工作原理详述

    转载请注明来自36大数据(36dsj.com):36大数据 » Hadoop分布式文件系统HDFS的工作原理详述 转注:读了这篇文章以后,觉得内容比较易懂,所以分享过来支持一下. Hadoop分布式文 ...

  3. Hadoop分布式文件系统HDFS的工作原理

    Hadoop分布式文件系统(HDFS)是一种被设计成适合运行在通用硬件上的分布式文件系统.HDFS是一个高度容错性的系统,适合部署在廉价的机器上.它能提供高吞吐量的数据访问,非常适合大规模数据集上的应 ...

  4. 一图看懂hadoop分布式文件存储系统HDFS工作原理

    一图看懂hadoop分布式文件存储系统HDFS工作原理

  5. 分布式协调服务ZooKeeper工作原理

    分布式协调服务ZooKeeper工作原理 原创 2016-02-19 杜亦舒 性能与架构 性能与架构 性能与架构 微信号 yogoup 功能介绍 网站性能提升与架构设计 大数据处理框架Hadoop.R ...

  6. centos 6.5环境下分布式文件系统MogileFS工作原理及分布式部署实现过程

    MogileFS是一套高效的文件自动备份组件,由Six Apart开发,广泛应用在包括LiveJournal等web2.0站点上 MogileFS由3个部分组成:    第1个部分:是server端, ...

  7. 套接字socket 的地址族和类型、工作原理、创建过程

    注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...

  8. 分布式文件系统之MogileFS的安装使用

    一.简介 MogileFS是一个开源的分布式文件存储系统,由LiveJournal旗下的Danga Interactive公司开发:它主要由三部分组成,第一部分是server端,server端主要包括 ...

  9. 一篇文章教会你理解Scrapy网络爬虫框架的工作原理和数据采集过程

    今天小编给大家详细的讲解一下Scrapy爬虫框架,希望对大家的学习有帮助. 1.Scrapy爬虫框架 Scrapy是一个使用Python编程语言编写的爬虫框架,任何人都可以根据自己的需求进行修改,并且 ...

随机推荐

  1. 5、VS2010+ASP.NET MVC4+EF4+JqueryEasyUI+Oracle该项目的开发——使用datagrid做报表

    来点需要:我使用的数据库访问EF框架,但是,因为使用一个动态表来的统计报告中.单独是每天产生基于数据表,它是很难使用EF加盟前.所以我包装在两组数据库存取层的框内,一个是EF,一种是传统的ADO.NE ...

  2. Testin一日游实验室发布的行级APP质量报告:在那里拍携程双赢

    Testin实验室公布国庆出行旅途类APP质量报告:携程力压去哪儿夺冠 2014/09/28 · Testin · 实验室报告 一年一度的十一黄金周即将临近,旅游软件成为每外出行人手机必装软件.为此全 ...

  3. 一张地图告诉你,只JavaScript不够!

    这将是JavaScript语法,你真的会一JavaScript嘛.看看这个图片!超好用JavaScript一本书的摘录游.熊儿.快去学习! 版权声明:本文博客原创文章.博客,未经同意,不得转载.

  4. Windows移动开发(一)——登堂入室

    開始本博客之前先分享一个自己的好消息吧,2014年3月31日起,正式就职于北京****集团Win8project师.主要负责将IOS和Android应用移植到Win8.1平板上,目标客户是银行,闲话不 ...

  5. 当<script>中的type等于text/html的妙用

    我们可以在<script>片断中定义一个被JS调用的代码,但代码又不在页面上显示,这时,我们可以使用下面的方法: <script id="commentTemplate&q ...

  6. C#操作Xml:使用XmlWriter写Xml

    假定创建了XmlWriter的实例变量xmlWriter,下文中将使用此实例变量写Xml 1.如何使用XmlWriter写Xml文档声明 ? // WriteStartDocument方法可以接受一个 ...

  7. 【MongoDB数据库】Java MongoDB CRUD Example

    上一页告诉我们MongoDB 命令入门初探,本篇blog将基于上一篇blog所建立的数据库和表完毕一个简单的Java MongoDB CRUD Example.利用Java连接MongoDB数据库,并 ...

  8. 换行符以及for循环的优化

    string str = ""; for (int i = 0; i < _errlistCusEmailInfo.Count; i++)                   ...

  9. 备份IIS httpd.ini 重写规则,兼容大部分版本号IISserver

    IISserver已经非常少,差点儿要退出市场了.nginx成为市场的主流. 备份一个httpd.ini,全部内容例如以下: [ISAPI_Rewrite] # 3600 = 1 hour Cache ...

  10. 什么是EF, 和 Entity Framework Demo简单构建一个良好的发展环境

     Entity Framwork(实体框架.缩写EF)这是ORM(Object Relational Mapping.对象映射关系)一个解决方案. EF的表映射为实体.并封装了操作方法.方便开发者 ...