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

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

作者: wz998 | 来源:发表于2018-12-18 11:53 被阅读0次

    上一篇文章详细讲解了怎么使用,这里完整的搭建一个图片服务器,并且列出使用的命令,详细的文档请看上一篇文章(https://www.jianshu.com/p/5e8dfb98fd86)和官方wiki(https://github.com/chrislusf/seaweedfs/wiki)。

    1.架构

    我们先了解一个概念:见附录

    一个master:

    作为cluster管理一个DataCenter名叫imgdatacenter1(抽象的概念);
    imgdatacenter1包含一个机柜 rack名叫imgrack1(抽象的概念);
    imgrack1机柜里面有一个DataNode名叫datanode1(可以认为DataNode是一个volume server );

    cd /home1/seaweeddir  //这是我的测试目录,你这里选择你自己的目录
    mkdir {mtmp,vtmp1,vtmp2,ftmp,mountdir}  //大括号内千万别多空格,否则会出现问题
    weed master -ip=localhost -port=9333 -mdir=./mtmp (mtmp是你自定义的保存生成的序列文件id的文件夹)
    

    一个DataNode:(datanode1只是抽象的名字没有实质的代码赋值,下面通过地址来区分DataNode)

    就是上面的datanode1,定义里面有10个volume,collection不先设置,DataCenter和rack都用下面的指令指定:

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

    此时就在名为imgdatacenter1的dataCenter中的名为imgrack1的rack里添加了一个地址为localhost:9991的volume server。

    一个filer服务器

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

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


    image.png

    然后启动filer服务

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

    本地映射filer

    mountdir 是本地任意目录,filer.path后面跟你想映射的filer中的目录,可以直接映射根目录。

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

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

    2.验证

    我们验证下我们的服务启动状态,
    此时有一个DataCenters名为imgdatacenter1,一个Racks名为imgrack1,一个DataNodes地址是localhost:9991,且该DataNode的Volumes个数为0,等我们新增文件的时候就会发现volumes个数才会增加

    //这种返回表示master启动成功且作为了leader
    curl "http://localhost:9333/cluster/status?pretty=y"
    {
      "IsLeader": true,
      "Leader": "localhost:9333"
    }
    
    //此时有一个DataCenters名为imgdatacenter1,一个Racks名为imgrack1,一个DataNodes地址是localhost:9991,且该DataNode的Volumes个数为0
    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"
    }
    

    本地操作的方式往服务器新增一个文件

    cd /home1/image/mountdir
    cp /home1/image/1.jpg ./
    

    我们查看下系统状态,(详细数据参见附录:上传文件后的系统状态)
    此时我们发现地址为localhost:9991的datanode的Volumes数量变成了7个,说明当前新增了7个volume,因为我们之前设置的volume最大个数时10,所有最多还能再新增3个volume。
    我们再看layouts,发现已经不是之前的null了,而是出现了一个名为""的collection,有七个可以写的volume。
    这是因为如果我们没有指定collection的时候,默认所有数据都保存在名为""的collection中

    我们查看下文件上传后volumeserver的状态
    我们发现id为4的volume的filecount为1,说明该文件上传到了这里。

    我们你再看下filer的状态
    多了个1.jpg文件

    我们再看下我们的挂载目录

    ls /home1/seaweeddir/mountdir/
    1.jpg
    

    此时说明我们上传文件就成功了

    此时我们可以操作本地文件系统中的目录/home1/seaweeddir/mountdir,来操作我们的图片服务器。
    然而批量操作本地文件系统的mount文件夹时不是并发的,需要经过fuse层,要想并发操作就需要直接操作filer服务。

    通过filer服务器做一些文件操作

    使用命令上传

    curl -F file=@report.js "http://localhost:8888/javascript/new_name.js"    # upload the file with a different name
    

    本地批量上传文件

    使用weed filer.copy file_or_dir1 [file_or_dir2 file_or_dir3] http://localhost:8888/path/to/a/folder/ (多线程且绕过fuse层)
    我在本地/home1/image/staff 下有大量的图片,这里上传到filer服务器的mystaff下,我们查看/home1/seaweeddir/mountdir/下,会发现多了个staff目录,且目录下也全部拷贝了图片。

    weed filer.copy /home1/image/staff http://localhost:8888/mystaff
    

    删除文件

    curl -X DELETE http://localhost:8888/path/to/file
    

    删除文件夹

    curl -X DELETE http://localhost:8888/path/to/dir?recursive=true
    

    一些注意事项

    1.关闭volume mount时需要手动sudo mount -l /home1/seaweeddir/mountdir目录,否则该目录会导致终端卡死。
    2.删除操作不会马上清空磁盘,要想实时清空未使用的空间,请执行
    curl "http://localhost:9333/vol/vacuum"

    使用fid操作文件在filer的显示

    curl http://localhost:9333/dir/assign
    {"fid":"7,03a0146c8ac8","url":"localhost:9991","publicUrl":"localhost:9991","count":1}
    
    curl -F file=@/home1/image/1.jpg http://localhost:9991/7,03a0146c8ac8 //在filer中找不到,因为filer服务没有保存映射关系,所有想使用filer,就得使用filer上传文件,否则只能通过fid获取信息。
    curl -F file=@/home1/image/1.jpg "http://localhost:8888/javascript/2.jpg"//在filer的javascript目录下多了个2.jpg
    
    weed download -server="localhost:9333" -dir="D:\data3" 4,012d48fa67 //可以通过fid下载文件
    

    结尾

    到这里一个图片服务器就搭建起来了,
    真正要熟悉使用seaweedfs需要仔细阅读官方wiki,并且查看源码和实现依赖的论文来了解实现原理。
    剩余的像数据备份,服务器云备份等请看官网wiki:
    https://github.com/chrislusf/seaweedfs/wiki/Failover-Master-Server
    https://github.com/chrislusf/seaweedfs/wiki/Amazon-S3-API
    https://github.com/chrislusf/seaweedfs/wiki/Async-Replication-to-another-Filer

    总结

    cd /home1/seaweeddir 
    mkdir {mtmp,vtmp1,vtmp2,ftmp,mountdir} 
    weed scaffold -config=filer -output=. 
    vim filer.toml (修改leveldb的dir为"./ftmp")
    weed master -ip=localhost -port=9333 -mdir=./mtmp
    weed volume  -dataCenter=imgdatacenter1 -rack=imgrack1  -ip=localhost -port=9991 -dir=./vtmp1 -max=10 -mserver=localhost:9333
    weed filer -ip=localhost -port=8888  -master=localhost:9333 -collection=test
    sudo weed mount -filer=localhost:8888 -dir=/home1/seaweeddir/mountdir -filer.path=/   -collection=test
    //关闭服务后执行 sudo umount -l /home1/seaweeddir/mountdir 取消挂载
    //此时就可以使用filer通过web操作文件了,而且也可以通过/home1/seaweeddir/mountdir本地操作文件了。
    //或者这么理解,sudo weed mount只能用sudo umount -l 取消挂载,而不是直接kill进程。
    

    附录:

    其他上传下载的命令

    weed upload -master=localhost:9333 file1 [file2 file3]
    weed upload -master=localhost:9333 -dir=one_directory -include=*.pdf
    
    //指定几个fid下载到本地one_directory中
    weed download -server=localhost:9333 -dir=one_directory fid1 [fid2 fid3 ...]
    
    //导出id为7的volume到/dir/name.tar,/tmp是volume保存的地址,只导出比2006-01-02T15:04:05新的文件
    weed export -dir=/tmp -volumeId=7 -o=/home1/seaweeddir/exp2/name.tar -fileNameFormat={{.Name}} -newer='2006-01-02T15:04:05'
    

    一些概念

    1.topology 是树状结构,DataNode 是树的叶子节点, DataCenter 和 Rack 是树的非叶子节点, DataCenter 是 Rack 的父母节点。
    2.在 MasterServer 维护的拓扑结构里, 是把 VolumeServer 的相关信息存储在 DataNode 里,每次查找对应的DataNode,都需要从 DataCenter -> Rack -> DataNode 依次找下去。
    3."fid":"1,01f96b93eb" 就是 Fid,Fid 由三个部分组成 【VolumeId, NeedleId, Cookie】 组成

        VolumeId: 1 32bit 存储的物理卷的Id 
        NeedleId: 01 64bit 全局唯一NeedleId,每个存储的文件都不一样(除了互为备份的)。
        Cookie: f96b93eb 32bit Cookie值,为了安全起见,防止恶意攻击
    

    4.VolumeId 是由 MasterServer 分配给 VolumeServer, 每个 VolumeServer 都维护个 n 个 Volume , 每个Volume 都有一个专属 VolumeId,之后会细说。 Needle 属于 Volume 里面的一个单元
    5.dir 就是该 Volume 所在的目录,
    6.Collection 很有用,每个 Volume 只能对应同一个 Collection,不同 Collection 的图片存储在不同 Volume,所以同一个 Volume 只能针对某一个 Collection ,而 同一个 Collection 的图片可能分布在不同的 Volume
    7.Replication 和 Topology 严重相关,比如在 001 模式,即在同一个 rack 中的不同 DataNode 中备份一份。假设在 rack1 中含有 DataNode1, DataNode2, DataNode3 三个数据节点中【随机】选出两个数据节点, 比如选出 DataNode1, DataNode2 然后同时写入这两个数据节点。 假设 rack1 只有一个数据节点的时候,而备份模式是 001 模式, 则无法正常备份,服务会报错。
    8.VolumeServer 启动时, 未申请任何 Volume,当第一次 /dir/assign 的时候, 会分配 Volume
    9.每个 VolumeServer 默认的 Volume 大小是 7 。默认情况下,当一个 VolumeServer 使用的磁盘超过 7 *30G = 210G 之后, 该 VolumeServer 属于只读状态, MasterServer 不会再分配新的 Fid 给它。
    10.每个 MasterServer 通过 Topology 维护多个 VolumeServer 。
    11.每个 VolumeServer 维护多个 Volume 。
    12.每个 Volume 包含多个 Needle ,Needle 即文件。
    13.多台 VolumeServer 之间的多机备份实现是强一致性。
    14.多台 MasterServer 之间的主从关系是是通过 goraft 实现。

    collection的说明

    如果我们没有指定collection的时候,默认所有数据都保存在名为""的collection中,
    0.按照collection删除

    Delete Collection
    curl "http://localhost:9333/col/delete?collection=xxx&pretty=y"
    

    1.预申请volume的时候指定collection

    //预申请4个属于名为turbo的collection 的volume
    curl "http://localhost:9333/vol/grow?collection=turbo&count=4"
    

    2.添加filer时指定collection

    //此时所有通过filer新增的数据都在名为myfiler的collection中
    weed filer -ip=localhost -port=8888  -master=localhost:9333  -collection=myfiler
    
    1. mount时指定collection
    //只挂在指定collection
    weed mount -filer=localhost:8888 -dir=~/folder_on_seaweedfs -filer.path=/home/chris -collection=chris
    

    4.其他

    curl "http://127.0.0.1:9333/dir/assign?collection=pictures"
    curl -F @file=./hello1.txt http://10.0.40.58:9333/submit?collection=test_crash
    weed upload -collection myfiles -master=localhost:9333 XXX.txt
    

    上传文件后的系统状态

    curl "http://localhost:9333/dir/status?pretty=y"
    {
      "Topology": {
        "DataCenters": [
          {
            "Free": 3,
            "Id": "imgdatacenter1",
            "Max": 10,
            "Racks": [
              {
                "DataNodes": [
                  {
                    "Free": 3,
                    "Max": 10,
                    "PublicUrl": "localhost:9991",
                    "Url": "localhost:9991",
                    "Volumes": 7
                  }
                ],
                "Free": 3,
                "Id": "imgrack1",
                "Max": 10
              }
            ]
          }
        ],
        "Free": 3,
        "Max": 10,
        "layouts": [
          {
            "collection": "",
            "replication": "000",
            "ttl": "",
            "writables": [
              1,
              2,
              3,
              4,
              5,
              6,
              7
            ]
          }
        ]
      },
      "Version": "1.10"
    }
    

    我们查看下文件上传后volumeserver的状态
    我们发现id为4的volume的filecount为1,说明该文件上传到了这里。

    curl "http://localhost:9991/status?pretty=y"
    {
      "Version": "1.10",
      "Volumes": [
        {
          "Id": 1,
          "Size": 0,
          "ReplicaPlacement": {
            "SameRackCount": 0,
            "DiffRackCount": 0,
            "DiffDataCenterCount": 0
          },
          "Ttl": {},
          "Collection": "",
          "Version": 3,
          "FileCount": 0,
          "DeleteCount": 0,
          "DeletedByteCount": 0,
          "ReadOnly": false
        },
        {
          "Id": 2,
          "Size": 0,
          "ReplicaPlacement": {
            "SameRackCount": 0,
            "DiffRackCount": 0,
            "DiffDataCenterCount": 0
          },
          "Ttl": {},
          "Collection": "",
          "Version": 3,
          "FileCount": 0,
          "DeleteCount": 0,
          "DeletedByteCount": 0,
          "ReadOnly": false
        },
        {
          "Id": 3,
          "Size": 0,
          "ReplicaPlacement": {
            "SameRackCount": 0,
            "DiffRackCount": 0,
            "DiffDataCenterCount": 0
          },
          "Ttl": {},
          "Collection": "",
          "Version": 3,
          "FileCount": 0,
          "DeleteCount": 0,
          "DeletedByteCount": 0,
          "ReadOnly": false
        },
        {
          "Id": 4,
          "Size": 77285,
          "ReplicaPlacement": {
            "SameRackCount": 0,
            "DiffRackCount": 0,
            "DiffDataCenterCount": 0
          },
          "Ttl": {},
          "Collection": "",
          "Version": 3,
          "FileCount": 1,
          "DeleteCount": 0,
          "DeletedByteCount": 0,
          "ReadOnly": false
        },
        {
          "Id": 5,
          "Size": 0,
          "ReplicaPlacement": {
            "SameRackCount": 0,
            "DiffRackCount": 0,
            "DiffDataCenterCount": 0
          },
          "Ttl": {},
          "Collection": "",
          "Version": 3,
          "FileCount": 0,
          "DeleteCount": 0,
          "DeletedByteCount": 0,
          "ReadOnly": false
        },
        {
          "Id": 6,
          "Size": 0,
          "ReplicaPlacement": {
            "SameRackCount": 0,
            "DiffRackCount": 0,
            "DiffDataCenterCount": 0
          },
          "Ttl": {},
          "Collection": "",
          "Version": 3,
          "FileCount": 0,
          "DeleteCount": 0,
          "DeletedByteCount": 0,
          "ReadOnly": false
        },
        {
          "Id": 7,
          "Size": 0,
          "ReplicaPlacement": {
            "SameRackCount": 0,
            "DiffRackCount": 0,
            "DiffDataCenterCount": 0
          },
          "Ttl": {},
          "Collection": "",
          "Version": 3,
          "FileCount": 0,
          "DeleteCount": 0,
          "DeletedByteCount": 0,
          "ReadOnly": false
        }
      ]
    }
    

    我们你再看下filer的状态
    多了个1.jpg文件

    curl  -H "Accept: application/json" "http://localhost:8888/?pretty=y" 
    {
      "Path": "",
      "Entries": [
        {
          "FullPath": "/1.jpg",
          "Mtime": "2018-12-18T10:38:18+08:00",
          "Crtime": "2018-12-18T10:38:18+08:00",
          "Mode": 436,
          "Uid": 1000,
          "Gid": 1000,
          "Mime": "image/jpeg",
          "Replication": "",
          "Collection": "",
          "TtlSec": 0,
          "chunks": [
            {
              "file_id": "4,0189b08312",
              "size": 77244,
              "mtime": 1545100698715493243,
              "e_tag": "32f4abc5"
            }
          ]
        }
      ],
      "Limit": 100,
      "LastFileName": "1.jpg",
      "ShouldDisplayLoadMore": false
    }
    

    我们再看下我们的挂载目录

    ls /home1/seaweeddir/mountdir/
    1.jpg
    

    相关文章

      网友评论

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

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