美文网首页
使用seaweedfs搭建一个图片服务器 (上)

使用seaweedfs搭建一个图片服务器 (上)

作者: wz998 | 来源:发表于2018-12-17 19:25 被阅读0次

    从下面的地址下载weed并安装

    https://github.com/chrislusf/seaweedfs/releases

    了解下seaweedfs依赖的论文

    经典论文翻译导读之《Finding a needle in Haystack: Facebook’s photo storage》
    http://www.importnew.com/3292.html

    使用前先了解一些基础概念

    master 存储映射关系,文件和fid的映射关系 weed master 
    Node  系统抽象的结点,抽象为datacenter、rack、datanode
    datacenter 数据中心,包含多个rack,类似一个机房
    rack :属于一个datacenter,类似机房中的一个机架  
    datanode : volume server ,存储节点,存储多个volume,类似机架中的一个机器 weed volume
    volume :逻辑卷,存储needle
    needle: 逻辑卷中的object,对应存储的文件
    collection:文件集,默认所有文件都属于""文件集。如果想给某些文件单独分类,可以在申请id的时候指定相同的文件集
    filer :指向一个或多个master的file服务器,多个使用逗号隔开。  weed filer
    

    下面一张图总结下相互关系:


    weed.jpg

    weed的基础命令

    weed master

    weed master 创建的是一个master服务器。
    参数:
    -defaultReplication string 备份策略(详细见https://github.com/chrislusf/seaweedfs/wiki/Replication
    -ip string
    -mdir string 选项用于配置保存生成的序列文件id的文件夹
    -port int (default 9333)
    -volumeSizeLimitMB uint 自定义不能大于30000(default 30000)
    -whiteList string 白名单,ip地址用逗号隔开

    master服务器可以创建多个来实现故障转移主服务器,详细见https://github.com/chrislusf/seaweedfs/wiki/Failover-Master-Server

    weed volume

    参数:
    -dir string 数据保存的路径,如果master的mdir没有指定会使用这个,如果filer的dir没有指定会新增并使用该目录下的filer目录
    -ip string
    -mserver string (default "localhost:9333")
    -port
    -dataCenter string
    -rack string
    -whiteList string

    weed volume会创建一个 datanode ,可以指定所属的 datacenter rack和master ,会根据配置存储文件,默认一开始没有volume,当开始存储文件的时候才会创建一个volume,当这一个volume大小超过了volumeSizeLimitMB 就会新增一个volume,当volume个数超过了max则该datanode就不能新增数据了。那就需要在通过weed volume命令新增一个datanode。

    weed filer

    weed filer
    参数
    -collection string 所有数据将存储在此集合中
    -dataCenter string 更倾向于在这个数据中心写入卷
    -dirListLimit int limit sub dir listing size (default 100000)
    -ip string
    -master string
    -port int(default 8888)

    更详细的说明请见:https://mp.csdn.net/mdeditor/85049078#
    或者访问官网wiki :https://github.com/chrislusf/seaweedfs/wiki

    这里正式搭建一个图片服务器

    一个master 默认不备份;

     //master需要的文件夹 mtmp
     //某一个datanode需要的文件夹vtmp1 vtmp2
     //filer服务器需要的文件夹ftmp
    mkdir {mtmp,vtmp1,vtmp2,ftmp}  //大括号内千万别多空格,否则会出现问题
    weed master -ip=localhost -port=9333 -mdir=./mtmp (mtmp是你自定义的保存生成的序列文件id的文件夹)
    

    出现如下提示说明启动成功


    image.png

    执行下面的命令:

    curl "http://localhost:9333/cluster/status?pretty=y"
    {
      "IsLeader": true,
      "Leader": "localhost:9333"
    }
    curl "http://localhost:9333/dir/status?pretty=y"
    {
      "Topology": {
        "DataCenters": null,
        "Free": 0,
        "Max": 0,
        "layouts": null
      },
      "Version": "1.10"
    

    出现DataCenters是null的原因是没有执行weed volume创建DataCenter。

    " 这里说一下抽象概念":
    我们抽象的认为我们的图片服务器,一个master需要两个datacenter叫imgdatacenter1,imgdatacenter2;imgdatacenter1需要两个rack叫imgrack1,imgrack2;然后imgrack1需要两个datanode1,datanode2;

    创建datanode

    创建datanode时 ,统一设置每个datanode包含10个volume即可。当datanode里面的volume满了以后再创建 新的datanode即可,方便扩展,并且不同datanode可以在不同磁盘位置;

    imgdatacenter1->imgrack1->datanode1:
      weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1  -ip=localhost -port=9991 -dir=./vtmp1 -max=10 -mserver=localhost:9333
    imgdatacenter1->imgrack1->datanode2:
      weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1 -port=9992 -dir=./vtmp2 -max=10 -mserver=localhost:9333
    

    (imgdatacenter1的imgrack2和imgdatacenter2按照上面的方式创建即可,见附录 )
    目前我们只是用imgdatacenter1->imgrack1->datanode1中的datanode1 :
    创建datanode1的时候 master命令行会打印,提示leader新增child imgdatacenter1成功;imgdatacenter1新增child imgrack1成功;imgdatacenter1,imgrack1新增child 9991成功;volume server在9991端口。


    image.png

    此时再执行查看master状态的命名;
    DataCenters Racks DataNodes都存在了;
    但是名为localhost:9991的datanode中的volumes为0,明明我们设置了10啊;
    因为没有上传文件之前不会创建volume,volume会在上传文件的时候根据实际情况创建。
    这里注意下layouts,现在是null,当上传文件的时候会出现一个名为""的collection,里面的writables就是volume 的id数组,如果你自定义了collection,name你自定义的collection也会出现在这里,并且所有collection的volume个数之和小于等于我们设置的10;
    collection删除后再新增,里面的volume的id会一直递增,不会使用原先删除的volume id。

    curl "http://localhost:9333/dir/status?pretty=y"
    {
      "Topology": {
        "DataCenters": [
          {
            "Free": 10,
            "Id": "imgdatacenter1",
            "Max": 10,
            "Racks": [
              {
                "DataNodes": [
                  {
                    "Free": 10,
                    "Max": 10,
                    "PublicUrl": "localhost:9991",
                    "Url": "localhost:9991",
                    "Volumes": 0
                  }
                ],
                "Free": 10,
                "Id": "imgrack1",
                "Max": 10
              }
            ]
          }
        ],
        "Free": 10,
        "Max": 10,
        "layouts": null
      },
      "Version": "1.10"
    }
    

    此时我们可以上传文件了。
    上传文件有多种方式,这里我们先说明两个
    1.先向master申请文件id,然后用文件id向datanode上传文件:

    curl http://localhost:9333/dir/assign
    {"fid":"1,015b7256d5","url":"localhost:9991","publicUrl":"localhost:9991","count":1}
    curl -F file=@/home1/image/1.jpg http://localhost:9991/1,015b7256d5
    {"name":"1.jpg","size":77244}
    

    修改只需要在fid上传别的文件即可
    上传成功后访问,只需要拼接url即可: localhost:9991/1,015b7256d5
    2.直接向master上传文件,master自己生成文件id,并向datanode上传文件,然后返回结果:

    curl -F file=@/home1/image/1.jpg http://localhost:9333/submit
    {"eTag":"32f4abc5","fid":"3,0265d4ab5f","fileName":"1.jpg","fileUrl":"localhost:9991/3,0265d4ab5f","size":77244}
    

    此时你再查看状态发现volume就创建了10个。

    curl "http://localhost:9333/dir/status?pretty=y"
    

    此时查看datanode的状态:

    curl "http://localhost:9991/status?pretty=y"
    //因为我1.jpg上传了两次,而且第一次在id为1的volume中,第二次在id为3的volume中,所有你会发现这两个id的volume的FileCount都为1。
    

    因为我1.jpg上传了两次,而且第一次在id为1的volume中,第二次在id为3的volume中,所有你会发现这两个id的volume的FileCount都为1

    并发的上传文件:
    一个卷服务器一次只写一个卷。如果需要增加并发性,可以预先分配大量卷。下面是例子。您还可以组合所有不同的选项。状态详情见附录

    //新增三个属于collection=imgcoll的volume,使用该命令时选查看有没有多余的volume可以创建
    //(curl "http://localhost:9333/dir/status?pretty=y")
    curl "http://localhost:9333/vol/grow?collection=imgcoll&count=3" 
    //文件集collection 是可选的选项,加上在删除的时候可以使用collection批量删除
    curl "http://localhost:9333/col/delete?collection=imgcoll&pretty=y"
    

    删除文件:

    curl -X DELETE http://localhost:9991/1,015b7256d5
    

    文件的删除不是实时的,因为weed默认有个阈值,超过这个阈值才会清理没使用的空间,如果你一时间内删除了大量文件,想立马生效,可以用这种方式清理未使用的空间:

    curl "http://localhost:9333/vol/vacuum"
    

    此时文件通过url的增删改查都可以了,下面把服务映射成文件系统来操作,可以方便的操作本地的大量文件

    一个filer

    filer是将文件以文件目录的方式上传到图片服务,然后你根据文件目录的方式访问

    weed scaffold -config=filer -output=.      //先生成filer.toml文件
    

    默认使用leveldb保存映射关系,打开filer.toml文件修改保存映射文件的文件夹为ftmp(自定义)


    image.png

    然后启动filer服务

    weed filer -ip=localhost -port=8888  -master=localhost:9333 
    

    master打印如下信息说明成功


    image.png

    自身的log


    image.png
    curl -F file=@report.js "http://localhost:8888/javascript/new_name.js"
     curl  -H "Accept: application/json" "http://localhost:8888/javascript/?pretty=y"  
    curl -X DELETE http://localhost:8888/path/to/file //删除文件
    curl -X DELETE http://localhost:8888/path/to/dir?recursive=true //删除文件夹
    
    curl  "http://localhost:8888/javascript/?pretty=y&lastFileName=new_name.js&limit=2" //对于大量文件的分页显示
    

    直接往weed filer中拷贝目录或者文件(-include是文件模式通配符前使用??)
    weed filer.copy nginxdir http://localhost:8888/aaa 把nginxdir拷贝到aaa目录下
    weed filer.copy -include *.go . http://localhost:8888/github/
    详细请见https://github.com/chrislusf/seaweedfs/wiki/Filer-Server-API

    本地映射filer

    然而我们时长会有这样的需求,批量把照片保存成图片文件备份起来,而不是备份一个bat文件;
    或者我们想以目录结构的方式通过本地访问,而不是通过web访问?
    此时最简单有效的方法就是把filer服务器mount到本地,然后直接操作文件系统:
    weed mount 像访问本地目录一样访问文件系统,前提是开启了 master volume filer
    (它使用bazil.org/FUSE,它允许在Linux和OSX上编写FUSE文件系统。在OSX上,它需要OSXFUSE)

    weed mount -filer=localhost:8888 -dir=~/mdir(本地目录) -filer.path=/aaa(上传的filer中的目录)
    

    可以指定 collection

    weed mount -filer=localhost:8888 -dir=~/folder_on_seaweedfs -filer.path=/home/chris -collection=chris
    

    关闭挂在需要关闭mount并且手动umont ~/mdir目录,如果一般用户失败请使用root用户



    附录

    一个场景:
    如果本地已经有很多文件了,如何快速的迁移到seaweedfs中呢?
    1.启动master、volume、filer
    2.启动mount
    3.手动拷贝到mount目录中(单线程的)
    4.使用weed filer.copy file_or_dir1 [file_or_dir2 file_or_dir3] http://localhost:8888/path/to/a/folder/ (多线程且绕过fuse层)

    aws s3 兼容
    Each bucket is stored in one collection, and mapped to folder /buckets/<bucket_name> by default
    可以通过删除collection来快速删除一个bucket

    异步复制
    应该有两个SeawideFileSystems运行,可能跨数据中心运行。每个服务器都应该有自己的文件服务器、主服务器和卷服务器。

    mkdir {vtmp3,vtmp4,vtmp5,vtmp6,vtmp7,vtmp8}
    imgdatacenter1->imgrack2->datanode1:
      weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1 -port=9993 -dir=./vtmp3 -max=10 -mserver=localhost:9333
    imgdatacenter1->imgrack2->datanode2:
      weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1 -port=9994 -dir=./vtmp4 -max=10 -mserver=localhost:9333
    
    imgdatacenter2->imgrack1->datanode1:
      weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1 -port=9995 -dir=./vtmp5 -max=10 -mserver=localhost:9333
    imgdatacenter2->imgrack1->datanode2:
      weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1 -port=9996 -dir=./vtmp6 -max=10 -mserver=localhost:9333
    
    imgdatacenter2->imgrack2->datanode1:
      weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1 -port=9997 -dir=./vtmp7 -max=10 -mserver=localhost:9333
    imgdatacenter2->imgrack2->datanode2:
      weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1 -port=9998 -dir=./vtmp8 -max=10 -mserver=localhost:9333
    

    这是我执行了(curl "http://localhost:9333/vol/grow?collection=imgcoll&count=3" )的结果

    {
      "Topology": {
        "DataCenters": [
          {
            "Free": 0,
            "Id": "imgdatacenter1",
            "Max": 10,
            "Racks": [
              {
                "DataNodes": [
                  {
                    "Free": 0,
                    "Max": 10,
                    "PublicUrl": "localhost:9991",
                    "Url": "localhost:9991",
                    "Volumes": 10
                  }
                ],
                "Free": 0,
                "Id": "imgrack1",
                "Max": 10
              }
            ]
          }
        ],
        "Free": 0,
        "Max": 10,
        "layouts": [
          {
            "collection": "",
            "replication": "000",
            "ttl": "",
            "writables": [
              1,
              2,
              3,
              4,
              5,
              6,
              7
            ]
          },
          {
            "collection": "imgcoll",
            "replication": "000",
            "ttl": "",
            "writables": [
              11,
              12,
              13
            ]
          }
        ]
      },
      "Version": "1.10"
    }
    

    详细文档请见官方wiki
    https://github.com/chrislusf/seaweedfs/wiki/Getting-Started

    相关文章

      网友评论

          本文标题:使用seaweedfs搭建一个图片服务器 (上)

          本文链接:https://www.haomeiwen.com/subject/txyckqtx.html