基于mongoDB和C#分布式海量文件存储实验
2012-05-28 09:34
811 查看
本实验将按以下几步进行:实验环境monodevelop ,ubuntu10.04,实验目的:探索分布式文件存储方案
1、单机小文件的存储,逐步增加上传文件的大小,观察mongoDB中文件对磁盘分配大小的变化。
2、采用分片的方式存储大量的数据
实验一:
首先建立一个数据库gywdb,上传一个574.5kB大小的文件,代码如下:
View Code
View Code
View Code
首先通过以下命令观察root@ubuntu:/data/shard/s0/userDB# ls -l
总用量 2048028
drwxr-xr-x 2 root root 4096 2012-05-27 17:22 _tmp
-rw------- 1 root root 67108864 2012-05-27 17:22 userDB.0
-rw------- 1 root root 134217728 2012-05-27 17:22 userDB.1
-rw------- 1 root root 268435456 2012-05-27 17:22 userDB.2
-rw------- 1 root root 536870912 2012-05-27 17:22 userDB.3
-rw------- 1 root root 1073741824 2012-05-27 17:22 userDB.4
-rw------- 1 root root 16777216 2012-05-27 17:22 userDB.ns
发现文件还是被存到默认的分片服务器0上。分片1上的数据还没有。尽管文件的总大小已经达到了需要分片存储的条件,即块的大小200MB
因此下面需要重新设置路由服务器,使其对集合userDB.userdata.chunks(这个里面存储了用户上传的文件)进行分片。
要想实现海量数据的分布式存储,那么就要对集合进行分片,因此片键的选择是至关重要的,它直接决定了集群中数据分布是否均衡、集群性能是否合理。那么我们究竟该选择什么样的字段来作为分片Key呢?这是个需要反复实践总结的地方。由于这里利用了分布式文件系统GridFS,因此有几点要说明(碰到错误,在网上查到的http://blog.csdn.net/zhangzhaokun/article/details/6324389):GridFS
根据需求的不同,GridFS有几种不同的分片方法。基于预先存在的索引是惯用的分片办法:
1)“files”集合(Collection)不会分片,所有的文件记录都会位于一个分片上,高度推荐使该分片保持高度灵活(至少使用由3个节点构成的replica set)。
2)“chunks”集合(Collection)应该被分片,并且用索引”files_id:1”。已经存在的由MongoDB的驱动来创建的“files_id,n”索引不能用作分片Key(这个是一个分片约束,后续会被修复),所以不得不创建一个独立的”files_id”索引。使用“files_id”作为分片Key的原因是一个特定的文件的所有Chunks都是在相同的分片上,非常安全并且允许运行“filemd5”命令(要求特定的驱动)。
前面已经分析过,在userDB.userdata.chunks集合中每一个记录都有一个字段file_id,代表了此块属于哪个文件,因此这里建一个以file_id的索引,以此字段键做为片键,同一个文件的块会被分配到同一个分片下
mongos> db.userdata.chunks.ensureIndex({files_id:1})
设置片键的命令如下:
mongos> db.runCommand({shardcollection:"userDB.userdata.chunks",key:{files_id:1}}
{ "collectionsharded" : "userDB.userdata.chunks", "ok" : 1 }
再次查看此表的状态: "sharded" : true说明此集合被分片了。
mongos> db.userdata.chunks.stats()
{
"sharded" : true,
"flags" : 1,
"ns" : "userDB.userdata.chunks",
"count" : 2022,
"numExtents" : 19,
"size" : 529953820,
"storageSize" : 538714112,
"totalIndexSize" : 245280,
"indexSizes" : {
"_id_" : 73584,
"files_id_1" : 73584,
"files_id_1_n_1" : 98112
},
"avgObjSize" : 262093.87734915924,
"nindexes" : 3,
"nchunks" : 2,
"shards" : {
"shard0000" : {
"ns" : "userDB.userdata.chunks",
"count" : 2022,
"size" : 529953820,
"avgObjSize" : 262093.87734915924,
"storageSize" : 538714112,
"numExtents" : 19,
"nindexes" : 3,
"lastExtentSize" : 93306880,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 245280,
"indexSizes" : {
"_id_" : 73584,
"files_id_1_n_1" : 98112,
"files_id_1" : 73584
},
"ok" : 1
}
},
"ok" : 1
}
多次执行如下代码上传文件后:执行如下命令观看系统中存在的文件
mongos> db.userdata.files.find()
{ "_id" : ObjectId("4fc1ec6c1d41c809ed4230d3"), "filename" : "微软官方2010年宽屏PPT图表全集400张锐普PPT论坛首发", "length" : 117652480, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T08:57:16.676Z"), "md5" : "506810e215c773addc3ce10a035695d9" }
{ "_id" : ObjectId("4fc1f2451d41c80b0f29eda1"), "filename" : "软件源代码", "length" : 412116413, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T09:22:13.443Z"), "md5" : "28cadbb180093dbcd15b25f0e741ae0a" }
{ "_id" : ObjectId("4fc1fe7d1d41c80b4d4a17cb"), "filename" : "新的软件源代码", "length" : 412116413, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T10:14:21.845Z"), "md5" : "28cadbb180093dbcd15b25f0e741ae0a" }
{ "_id" : ObjectId("4fc212541d41c80ba8e1180f"), "filename" : "新微软PPT", "length" : 117652480, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T11:39:00.598Z"), "md5" : "506810e215c773addc3ce10a035695d9" }
{ "_id" : ObjectId("4fc21b9e1d41c80747e207e8"), "filename" : "新微软PPT1", "length" : 117652480, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T12:18:38.183Z"), "md5" : "506810e215c773addc3ce10a035695d9" }
可以看到实验上传了5个文件
执行以下命令观察文件分块后在集群中的部署情况:
mongos> db.userdata.chunks.stats()
{
"sharded" : true,
"flags" : 0,
"ns" : "userDB.userdata.chunks",
"count" : 4493,
"numExtents" : 35,
"size" : 1177568872,
"storageSize" : 1274904576,
"totalIndexSize" : 531440,
"indexSizes" : {
"_id_" : 163520,
"files_id_1" : 155344,
"files_id_1_n_1" : 212576
},
"avgObjSize" : 262089.66659247718,
"nindexes" : 3,
"nchunks" : 3,
"shards" : {
"shard0000" : {
"ns" : "userDB.userdata.chunks",
"count" : 4044,
"size" : 1059857256,
"avgObjSize" : 262081.4183976261,
"storageSize" : 1139773440,
"numExtents" : 23,
"nindexes" : 3,
"lastExtentSize" : 193486848,
"paddingFactor" : 1,
"flags" : 0,
"totalIndexSize" : 449680,
"indexSizes" : {
"_id_" : 138992,
"files_id_1_n_1" : 179872,
"files_id_1" : 130816
},
"ok" : 1
},
"shard0001" : {
"ns" : "userDB.userdata.chunks",
"count" : 449,
"size" : 117711616,
"avgObjSize" : 262163.95545657014,
"storageSize" : 135131136,
"numExtents" : 12,
"nindexes" : 3,
"lastExtentSize" : 26034176,
1、单机小文件的存储,逐步增加上传文件的大小,观察mongoDB中文件对磁盘分配大小的变化。
2、采用分片的方式存储大量的数据
实验一:
首先建立一个数据库gywdb,上传一个574.5kB大小的文件,代码如下:
View Code
View Code
View Code
using System; using System.Collections; using System.Collections.Generic; using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.GridFS; namespace mongoDBClient { class MainClass { public static void Main (string[] args) { //mongoDb服务实例连接字符串 string con="mongodb://localhost:40000"; //得到一个于mongoDB服务器连接的实例 MongoServer server=MongoServer.Create(con); //获得一个与具体数据库连接对象,数据库名为gywdb MongoDatabase mydb=server.GetDatabase("userDB"); //定义一个本地文件的路径字符串 string localFileName="/home/guoyuanwei/学习资料/Platform5.24.rar"; //定义mongoDB数据库中文件的名称 string mongoDBFileName="软件源代码"; //设置GridFS文件中对应的集合前缀名 MongoGridFSSettings fsSetting=new MongoGridFSSettings(){Root="userdata"}; //实例化一个GridFS MongoGridFS gridfs=new MongoGridFS(mydb,fsSetting); //将本地文件上传到mongoDB中去,以默认块的大小256KB对文件进行分块 gridfs.Upload(localFileName,mongoDBFileName); } } }
首先通过以下命令观察root@ubuntu:/data/shard/s0/userDB# ls -l
总用量 2048028
drwxr-xr-x 2 root root 4096 2012-05-27 17:22 _tmp
-rw------- 1 root root 67108864 2012-05-27 17:22 userDB.0
-rw------- 1 root root 134217728 2012-05-27 17:22 userDB.1
-rw------- 1 root root 268435456 2012-05-27 17:22 userDB.2
-rw------- 1 root root 536870912 2012-05-27 17:22 userDB.3
-rw------- 1 root root 1073741824 2012-05-27 17:22 userDB.4
-rw------- 1 root root 16777216 2012-05-27 17:22 userDB.ns
发现文件还是被存到默认的分片服务器0上。分片1上的数据还没有。尽管文件的总大小已经达到了需要分片存储的条件,即块的大小200MB
因此下面需要重新设置路由服务器,使其对集合userDB.userdata.chunks(这个里面存储了用户上传的文件)进行分片。
要想实现海量数据的分布式存储,那么就要对集合进行分片,因此片键的选择是至关重要的,它直接决定了集群中数据分布是否均衡、集群性能是否合理。那么我们究竟该选择什么样的字段来作为分片Key呢?这是个需要反复实践总结的地方。由于这里利用了分布式文件系统GridFS,因此有几点要说明(碰到错误,在网上查到的http://blog.csdn.net/zhangzhaokun/article/details/6324389):GridFS
根据需求的不同,GridFS有几种不同的分片方法。基于预先存在的索引是惯用的分片办法:
1)“files”集合(Collection)不会分片,所有的文件记录都会位于一个分片上,高度推荐使该分片保持高度灵活(至少使用由3个节点构成的replica set)。
2)“chunks”集合(Collection)应该被分片,并且用索引”files_id:1”。已经存在的由MongoDB的驱动来创建的“files_id,n”索引不能用作分片Key(这个是一个分片约束,后续会被修复),所以不得不创建一个独立的”files_id”索引。使用“files_id”作为分片Key的原因是一个特定的文件的所有Chunks都是在相同的分片上,非常安全并且允许运行“filemd5”命令(要求特定的驱动)。
前面已经分析过,在userDB.userdata.chunks集合中每一个记录都有一个字段file_id,代表了此块属于哪个文件,因此这里建一个以file_id的索引,以此字段键做为片键,同一个文件的块会被分配到同一个分片下
mongos> db.userdata.chunks.ensureIndex({files_id:1})
设置片键的命令如下:
mongos> db.runCommand({shardcollection:"userDB.userdata.chunks",key:{files_id:1}}
{ "collectionsharded" : "userDB.userdata.chunks", "ok" : 1 }
再次查看此表的状态: "sharded" : true说明此集合被分片了。
mongos> db.userdata.chunks.stats()
{
"sharded" : true,
"flags" : 1,
"ns" : "userDB.userdata.chunks",
"count" : 2022,
"numExtents" : 19,
"size" : 529953820,
"storageSize" : 538714112,
"totalIndexSize" : 245280,
"indexSizes" : {
"_id_" : 73584,
"files_id_1" : 73584,
"files_id_1_n_1" : 98112
},
"avgObjSize" : 262093.87734915924,
"nindexes" : 3,
"nchunks" : 2,
"shards" : {
"shard0000" : {
"ns" : "userDB.userdata.chunks",
"count" : 2022,
"size" : 529953820,
"avgObjSize" : 262093.87734915924,
"storageSize" : 538714112,
"numExtents" : 19,
"nindexes" : 3,
"lastExtentSize" : 93306880,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 245280,
"indexSizes" : {
"_id_" : 73584,
"files_id_1_n_1" : 98112,
"files_id_1" : 73584
},
"ok" : 1
}
},
"ok" : 1
}
多次执行如下代码上传文件后:执行如下命令观看系统中存在的文件
mongos> db.userdata.files.find()
{ "_id" : ObjectId("4fc1ec6c1d41c809ed4230d3"), "filename" : "微软官方2010年宽屏PPT图表全集400张锐普PPT论坛首发", "length" : 117652480, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T08:57:16.676Z"), "md5" : "506810e215c773addc3ce10a035695d9" }
{ "_id" : ObjectId("4fc1f2451d41c80b0f29eda1"), "filename" : "软件源代码", "length" : 412116413, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T09:22:13.443Z"), "md5" : "28cadbb180093dbcd15b25f0e741ae0a" }
{ "_id" : ObjectId("4fc1fe7d1d41c80b4d4a17cb"), "filename" : "新的软件源代码", "length" : 412116413, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T10:14:21.845Z"), "md5" : "28cadbb180093dbcd15b25f0e741ae0a" }
{ "_id" : ObjectId("4fc212541d41c80ba8e1180f"), "filename" : "新微软PPT", "length" : 117652480, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T11:39:00.598Z"), "md5" : "506810e215c773addc3ce10a035695d9" }
{ "_id" : ObjectId("4fc21b9e1d41c80747e207e8"), "filename" : "新微软PPT1", "length" : 117652480, "chunkSize" : 262144, "uploadDate" : ISODate("2012-05-27T12:18:38.183Z"), "md5" : "506810e215c773addc3ce10a035695d9" }
可以看到实验上传了5个文件
执行以下命令观察文件分块后在集群中的部署情况:
mongos> db.userdata.chunks.stats()
{
"sharded" : true,
"flags" : 0,
"ns" : "userDB.userdata.chunks",
"count" : 4493,
"numExtents" : 35,
"size" : 1177568872,
"storageSize" : 1274904576,
"totalIndexSize" : 531440,
"indexSizes" : {
"_id_" : 163520,
"files_id_1" : 155344,
"files_id_1_n_1" : 212576
},
"avgObjSize" : 262089.66659247718,
"nindexes" : 3,
"nchunks" : 3,
"shards" : {
"shard0000" : {
"ns" : "userDB.userdata.chunks",
"count" : 4044,
"size" : 1059857256,
"avgObjSize" : 262081.4183976261,
"storageSize" : 1139773440,
"numExtents" : 23,
"nindexes" : 3,
"lastExtentSize" : 193486848,
"paddingFactor" : 1,
"flags" : 0,
"totalIndexSize" : 449680,
"indexSizes" : {
"_id_" : 138992,
"files_id_1_n_1" : 179872,
"files_id_1" : 130816
},
"ok" : 1
},
"shard0001" : {
"ns" : "userDB.userdata.chunks",
"count" : 449,
"size" : 117711616,
"avgObjSize" : 262163.95545657014,
"storageSize" : 135131136,
"numExtents" : 12,
"nindexes" : 3,
"lastExtentSize" : 26034176,
相关文章推荐
- 基于mongoDB和C#分布式海量文件存储实验
- MongoDB一个基于分布式文件存储的数据库(介于关系数据库和非关系数据库之间的数据库)
- 基于分布式文件存储的数据库---MongoDB
- 一个基于分布式文件存储的数据库MongoDB
- GridFS:基于MongoDB的分布式文件存储系统
- MongoDB 基于分布式文件存储的开源数据库
- Mongodb 基于分布式文件存储的数据库
- 介绍一款基于分布式文件存储的数据库--MongoDB
- GridFS:基于MongoDB的分布式文件存储系统
- MongoDB一个基于分布式文件存储的数据库(介于关系数据库和非关系数据库之间的数据库)
- MongoDB 一个基于分布式文件存储的数据库
- GridFS:基于MongoDB的分布式文件存储系统
- MongoDB 基于分布式文件存储的数据库
- 基于haystack的分布式小文件存储系统bfs
- 用Mongodb基于GridFS存储文件
- 基于Mongodb进行分布式数据存储
- 使用Mongodb存储上传物理文件并进行SQUID加速(基于aspx页面)
- 使用Mongodb存储上传物理文件并进行SQUID加速(基于aspx页面)
- 基于Mongodb进行分布式数据存储
- MongoDB的分布式文件存储系统