微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

云存储服务

摘 要:最近云计算,云存储炒的是热火朝天,本蛙也来凑个热闹,和大家一起来DIY一个云存储服务。像live mesh目前就是个网络的OS,能把本机的东西存上去,也不是结构化的,我觉得云存储最好能够存储结构化的数据,而且管理起来要像数据库一样灵活。这样人 人都可以把自己的备忘录,联系人信息放在自己的云存储服务里,并且方便的访问。

项目网址:http://www.codeplex.com/wawcloudstoreservice/

思路:
1、对已通过身份验证的用户每人分配一个目录,在这个目录里动态创建sqliet数据库
2、提供一套webservice接口来让用户创建数据结构,添加获取及更新数据。
当然有人说了,人家google,亚马逊,ms的云存储多NB呀,自动负载均衡,高可靠性,速度又快,你这算啥呀,的确,我没有经过压力测试,不过据说 sqlite的性能还不错,当然没有bigtable和hoodlop那些玩意牛了,本文主要是提供一种思路,接口有了,以后的实现可以慢慢来,对吧,以 后慢慢来提高性能和稳定性,如果你做一个云存储服务一天就几百个人用,我觉得用sqlite都有点浪费,一切从需求出发。

困了,直接上代码算了,关于一些问题,咱们评论里再讨论

接口如下


namespace WasaSoft.StoreService

{

    
public enum DataStoreType

    

{

        Null,

        Integer,

        Real,

        Text,

        Blob,

        IdentityInteger,

    }


    
class DictionayItem<T,V>

    

{

        
 T Key;

        
 V Value;

    }

    [WebServiceBinding(ConformsTo 
= WsiProfiles.BasicProfile1_1, Name  "IDataStoreService", Namespace http://pim.fetionmm.com/IDataStoreService/)]

    
interface IDataStoreService

    

{

        [WebMethod(Description 
创建库)]

        
string CreateDataBase();

        [WebMethod(Description 
创建表 CreateTable( tableName, ListDictionayItem>> cols);

        [WebMethod(Description 
增加数据 Add( data);

        [WebMethod(Description 
获取所有数据 GetAll( cols,  orderCol,203);" face="Verdana">bool isDesc);

        [WebMethod(Description 
获取详细信息 GetDetail( identityCol,203);" face="Verdana"> colValue);

        [WebMethod(Description 
删除一条数据 DeleteOne(批量删除数据 DeleteSome( identityCols);

        [WebMethod(Description 
清空表 Clear( tableName);

        [WebMethod(Description 
更新数据 Update( colValue,203);" face="Verdana"> data);

    }

}



实现如下



[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo 
 WsiProfiles.BasicProfile1_1)]

[ToolBoxItem(
false)]

public class StoreService : WebService, IDataStoreService

{

    
privateconststring dbname @"E:/huhao/project/WawaCloudStoreService/StoreService/bin/test.db3;


    
#region IDataStoreService 成员


    
 CreateDataBase()

    

{

        
if (!File.Exists(dbname)) return出错;

        File.Delete(dbname);

        sqliteConnection.CreateFile(dbname);

        
ok;

    }
 CreateTable( tableName, List<DictionayItem, DataStoreType>> cols)

    

{

        DbProviderFactory factory 
 sqliteFactory.Instance;

        
using (DbConnection conn  factory.CreateConnection())

        

{

            conn.ConnectionString 
.Format(Data Source={0}dbname);

            conn.open();


            StringBuilder builder 
new StringBuilder();

            
int i 1;

            
foreach (DictionayItem> col in cols)

            

{

                
 colType  col.Value == DataStoreType.IdentityInteger

                                     
?INTEGER PRIMARY KEY

                                     : col.Value.ToString();

                builder.AppendFormat(
{0} {1}{2}++ cols.Count "" : );

            }


            
 sql create table [{0}] ({1})

            DbCommand cmd 
 conn.CreateCommand();

            cmd.Connection 
 conn;

            cmd.CommandText 
 sql;

            cmd.ExecuteNonQuery();


            
 sql;

        }

    }
 Add( data)

    

 factory.CreateConnection())

        

dbname);

            conn.open();

            DbCommand cmd 
 conn.CreateCommand();


            StringBuilder builder 
 StringBuilder();

            StringBuilder builder2 
for0; i  data.Count; i)

            

{

                builder.AppendFormat(
{0} {1}+ data.Count );

                builder2.AppendFormat(
?);

                cmd.Parameters.Add(cmd.CreateParameter());

            }
insert into {0} ({1})values({2})



            
)

            

{

                cmd.Parameters[i].Value 
 data[i].Value;

            }

            cmd.Connection 
 GetAll( cols,0);"> orderCol,255);">bool isDesc)

    

 factory.CreateConnection())

        

{

            StringBuilder builder 
 cols.Count; i)

            


            
select {0} from {1} ORDER BY {2} {3}

                                       isDesc 
descasc);


            sqliteDataAdapter dataAdapter 
 sqliteDataAdapter(sqldbname));

            DataSet ds 
 DataSet();

            dataAdapter.Fill(ds);


            StringWriter sw 
 StringWriter();

            ds.WriteXml(sw);

            
 sw.ToString();

        }
 GetDetail( identityCol,0);"> colValue)

    

 factory.CreateConnection())

        

 conn.CreateCommand();

            
select * from {0} where {1}=? limit 0,1

            cmd.Connection 
 sql;

            cmd.Parameters.Add(cmd.CreateParameter());

            cmd.Parameters[
].Value  colValue;

            sqliteDataAdapter dataAdapter 
 sqliteDataAdapter((sqliteCommand) cmd);

            DataSet ds 
 Update( colValue,

                 List
 data)

    

 factory.CreateConnection())

        

)

            

{0}=? {1}update {0} set {1} where {2}=?


            
)

            



            cmd.Parameters.Add(cmd.CreateParameter());

            cmd.Parameters[data.Count].Value 
 colValue;


            cmd.Connection 
 DeleteOne( colValue)

    

 factory.CreateConnection())

        

delete from {0} where {1}=? colValue;

            cmd.ExecuteNonQuery();

            
 DeleteSome( identityCols)

    

 s  identityCols)

        

{

            DeleteOne(tableName, identityCol, s);

        }

        
 Clear( tableName)

    

 factory.CreateConnection())

        

delete from {0}

            cmd.Connection 
 sql;

            cmd.ExecuteNonQuery();

            


 


    
#endregion

}



单元测试如下,其中StoreService.StoreService是web服务的代理类


 Program

staticvoid Main([] args)

    

try

        

{

            
 CreateDatabase

            StoreService.StoreService service 
 StoreService.StoreService();

            Console.WriteLine(service.CreateDataBase());

            Console.WriteLine(
创建数据库成功); 

            


            
 CreateTable

            List
DictionayItemOfStringDataStoreType cols  List();

            DictionayItemOfStringDataStoreType item 
 DictionayItemOfStringDataStoreType();

            item.Key 
id;

            item.Value 
 DataStoreType.IdentityInteger;

            cols.Add(item);


            item 
name DataStoreType.Text;

            cols.Add(item);


            item 
password DataStoreType.Text;

            cols.Add(item);


            Console.WriteLine(service.CreateTable(
mytable

            Console.WriteLine(
创建表成功


            
 AddDataDictionayItemOfStringString toAddData ();

            

            DictionayItemOfStringString dataItem 
 DictionayItemOfStringString();

            dataItem.Key 
;

            dataItem.Value 
蛙蛙王子;

            toAddData.Add(dataItem);


            dataItem 
www.cnblogs.com;

            toAddData.Add(dataItem);


            Console.WriteLine(service.Add(


            toAddData[
谁染枫林醉;

            toAddData[
www.fetionmm.com;

            Console.WriteLine(service.Add(
onlytiancai


            Console.WriteLine(
添加数据成功);

            


            
 GetAll

            Console.WriteLine(service.GetAll(
[]

{})); 

            Console.WriteLine(
获取所有数据成功


            
 GetDetails

            Console.WriteLine(service.GetDetail(
1));

            Console.WriteLine(
获取详细数据成功


            
 Update toUpdateData ();

            dataItem 
mm.fetionmm.com;

            toUpdateData.Add(dataItem);

            Console.WriteLine(service.Update(

            Console.WriteLine(service.GetAll(
[] 

 }更新数据成功


            
 DeleteOne

            Console.WriteLine(service.DeleteOne(
));

            Console.WriteLine(service.GetAll(
[] 

删除一条数据成功


            
 DeleteSome

            Console.WriteLine(service.DeleteSome(
[] 

2));

            Console.WriteLine(service.GetAll(
[] 

删除多条数据成功


            
 Clear

            Console.WriteLine(service.Clear(
));

            Console.WriteLine(service.GetAll(
[] 

清空数据成功



        }
catch (Exception ex)

        

{

            Console.Write(ex);

        }

        Console.ReadKey();

    }

}


相关链接
Setting a breakpoint in managed code using Windbg
http://blogs.msdn.com/kristoffer/archive/2007/01/02/setting-a-breakpoint-in-managed-code-using-windbg.aspx

[转]如何高效使用sqlite .net (C#)
http://www.cnblogs.com/yelsea/archive/2007/06/21/792314.html

sqlite.net 2.0使用笔记
http://www.sqlitechina.org/html/1/20071221/70.html

http://extrafliu.blogspot.com/search/label/Sqlite.net%202.0使用笔记

sqlite 第三版中的数据类型
http://www.sqlite.com.cn/MySqlite/5/127.Html

sqlite3数据类型的请教  
http://topic.csdn.net/u/20080825/23/e364b41f-2c56-499f-a7a2-7bc629b67c36.html

http://sourceforge.net/project/showfiles.php?group_id=132486

sqlite不支持sql语法总结
http://www.sqlite.com.cn/MySqlite/3/250.Html

101个Google技巧 - Google技巧的终极收集

http://www.cnbeta.com/articles/64073.htm

云计算
http://www.hudong.com/wiki/%E4%BA%91%E8%AE%A1%E7%AE%97

云中漫步——迎接云计算时代的到来
http://www.googlechinablog.com/2008/05/blog-post_09.html

《互联网周刊》:“云计算”的容量
http://www.cnbeta.com/articles/64169.htm

Google App Engine 初体验
http://www.javaeye.com/news/2066

Google App Engine入门
http://www.webfuny.cn/2008/08/09/app-engine-g.html

补充
这个服务写的很简单,要想真的投入使用,还要考虑很多东西
1、身份验证:web服务的身份验证一般用单独的soap header来做,可以把从单点登录获取的凭证放在soap header里,服务端取出凭证,验证凭证,获取用户信息,并找到用户的profile,比如用户数据库路径在哪里,是否是VIP用户数据库配额是多 少等等。关于基于令牌的web服务身份验证,可以看以下链接,http://www.cnblogs.com/onlytiancai/archive /2006/08/16/478095.html,当然这个方案很简单,没有使用对称加密等技术,关于SSO大家可以搜索一下相关帖子。
2、安全限制:安全在这里包括多方面,比如一个用户频繁的调用一个耗费资源很大的服务,或者传入一个超级大的参数,或者从数据库里select了10M的 数据,或者由于杀毒软件查杀数据库是否有病毒,访问数据库的众多线程被hang住,造成IIS线程池耗尽等,因为这些,所以要在web服务外层加一个安全 控制服务,控制用户的流量,以及细化代码,找出可能引擎服务器长时间执行的请求,把它拒绝掉。其它的sql语句等用户爱怎么写怎么写,反正数据库是它自己 的,弄坏了也怪他自己。然后还可以考虑给用户增加一些磁盘配额等措施。
3、异常处理:本文例子没有进行任何异常处理,web service用soap exception来处理错误,所以在服务端出现异常后要包装成soap exception返回给用户,关于这种操作,博客园有多人说过。
4、可靠性:用无数的sqliet数据库来保存用户信息,当然不是最可靠的方式,以后再考虑一些容错的方案,比如用开源的hadoop等。但是用户多了, 可以用多台机器来存储用户信息,前段收到用户请求后根据用户名的哈希值去寻找他的数据应该从哪台存储服务器上去读取,或者直接302重定向到另一台前端服 务器上,这也算是负载均衡了。
5、性能:考虑在前端做一些缓存服务,尤其是对读操作,设计良好的读缓存能很有效的提高服务器性能,因为大多数请求时读操作,写缓存也可以考虑,看写请求 的量来评估了,网上也有不少开源的缓存服务组件,Memcache,java的oscache,微软的企业库里的缓存块等,大家可以研究下用起来。

6、 前端展现:光有了服务不行,要想让用户使,还得有个界面,web服务自身的特性让它可以和多种平台交互,所以我们可以为这个服务做多界面的应用,用 delphi,c#,python甚至yui+google gear,只要能访问web服务,都可以做一个界面来使用我的云存储服务。当然app engine最大的特点就是有调用web服务的API,大家做app engine应用的时候可以考虑用下俺的云存储服务。

我 知道live mesh要把live id,live contacts,live mail,live desktop,live office都要集成到一起,微软内部还有reddog,BitVault等项目来对抗开源和google的map/reduce,hadoop,bigtable,gfs等东西的。我发此帖的意思是不是只有大 公司才能推出云这个云那个,自己有好的想法也能去实现去,现在云计算,云存储等概念都不成熟,甚至salesforce等托管CRM厂商也说自己是云计算 服务,还有adobe的Adobe Share和ms的windows live skydrive就是一个网络硬盘,也成为云存储,那其它的AllMyData、Box.net、eSnips、 Freepository、GoDaddy、iStorage、Mofile、 Mozy、Omnidrive、Openomy、Streamload、 Strongspace以及Xdrive等更是云存储了,我觉得这些东西本质上和FTP有啥区别呀,就是弄了一套rest api或者一个ajax ui,用户也就是在上面存储一些文档文件啥的,存结构化数据不方便(当然上面列举的一些产品和服务我没有一一进行详细的了解,是看资料了解的,有些可能说 的不对。)。其它还有sun的Hydrazine计划及Insight计划,亚马逊的EC2云计算服务,EBS云存储服务,IBM的蓝云计划等,当然大公 司争的是企业市场,我们自己做云服务就针对个人来展开了,或者是把某一点做精。

参考:
云计算井喷

http://server.zdnet.com.cn/server/2008/0422/825478.shtml

云计算——IBM的未来策略
http://laiba.tianya.cn/laiba/CommMsgs?cmm=14452&tid=2592400139121650923
IBM云计算数据中心
http://www.freerainbow.cn/2008/08/03/ibm-yunjisuan.html
亚马逊发力企业云计算市场

http://www.builder.com.cn/2008/0415/815771.shtml

Sun实施云计算Insight 计划挑战微软Live Mesh

http://www.cnzz.cn/NewsInfo/6180.aspx

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐