簡介
多少次你發現自己在幾個月的開發和無數的努力後陷入了毫無性能而言的web應用?多少次你在好奇如果你無法向普通用戶傳達快與最快的標准,你的客戶還應該把你當作專家?多少你聽到有關Google和Facebook一些糟糕的對比?讓我告訴你,我的客戶是怎麼看待這些的:
我曾開發一個有著復雜處理和過濾的web應用,因為很多業務規則和UI要求。再加上一些過時技術的第三方提供者,對於他們而言,速度意味著15年的工作丟進垃圾桶,然後重新開始。我的應用不是那麼快,有時處理一個請求花費6~8s才會處理完,業務規則的驗證、過濾和格式化響應。而客戶不接受這樣。並說如果Google做就會做好。同樣,Facebook也行。我無法向客戶解釋速度後面的硬件是多麼的龐大,服務器的壓力怎樣。我僅僅回復說可以做更好,我在記住Redis後保證可以做到。
那麼,在我們深入Redis之前,我先介紹下NoSql。
大多數開發者習慣用關系型數據庫。數據驅動開發或者領域驅動開發(作為一個整體框架編碼或者用Fluent API NHibernate),關系型數據庫的概念一樣。另一方面,NoSql引領了新的數據存儲時尚。在.NET社區最流行的是MongoDb,RavenDb和Redis。我已經寫了一篇怎麼使用MongDb的文章,你可以在這裡找到。我使用它記錄重要活動、錯誤和異常等的日志。
在NoSql的世界裡,概念和所有流行的數據庫基本是一樣的。基本上它是存在你機器上某處的JSon文檔或者你可以操作的某種.NET客戶機或驅動。NoSql的偉大之處在於它解決了關系型數據庫與OO語言如C#或Java時的一個主要缺點:錯配阻抗。
Redis其實和任何的NoSql數據庫一樣。但是它是一個內存數據庫而表現十分出色。
簡單的說,Redis可以給你難以置信的存取你的對象狀態的能力從而使你的應用更加快速。有時候,你的應用速度可以優化8到10倍。這並不是開玩笑的而且你不需要背後有Google或Facebook那樣的基礎設施。如果你想知道更多的關於Redis背後的思想和它的歷史的內容,可以上網查找更多。有很多文章是關於這些的。
Redis代表了遠程字典服務( Remote Dictionary Service) 。它是一個鍵值存儲就像C#的字典對象。所以讓我們看看如何使用:
首先,按照下面的步驟安裝並運行Redis:
因為Redis是一個字典,可以以如下方式保存鍵值:
復制代碼 代碼如下:Set schedule:1 "{'origin':'Montreal','destination':'Toronto'}"
在這個示例中的值是一個json對象。這意味著你可以向Redis中添加復雜的對象。但沒必要這麼做,因為Redis支持5種數據類型以滿足你的需求。
你也可以以如下方式指定key:
復制代碼 代碼如下:Set schedule:id 1
對於執行多個set 和get,可以使用mset 和mget來代替。我將不再對這些命令進行討論。你可以查看Redis文檔並盡情嘗試。
幕後
到目前為止我們所做的一切都打破了常規。但在幕後卻是Redis客戶端通過Redis協議向服務器發送指令。服務器對內存中的數據執行這些指令,並返回響應結果。
做為服務的Redis
你可以在物理機,虛擬機上使用Redis,也可以將Redis做為雲服務。很多像Digital Ocean和Widnows Azure這類的供應商都提供該服務。我們將從Digital Ocean開始(主要考慮到價錢,並且我認為Azure的Redis服務有點貴)
我們使用PuTTY的ssh(安全連接模式)來連接到Digital Ocean。下載PuTTY並將IP地址配置為你的DO droplet地址(droplet是你在DO上創建的linux主機)。然後啟動PuTTY並用DO提供的root賬戶和密碼登錄。運行以下命令以保持你的linux主機的更新:apt-get update (linux用戶現在很激動吧).
現在你正在或已經保持更新了。然後運行apt-get install build-essential為你的linux服務器安裝所有缺失的工具。哦了。另外對於這些設置還有很多更詳細的博文。我不得不承認,因為我對linux世界不太熟悉,所以在配置的時候著實費了翻手腳。
在 Visual Studio 中使用
在起始頁,添加一個MVC項目,並使用Nuget包管理器添加Servicestack.redis。這樣你就可以連接到Redis並做一些有意思的事。
你需要按以下步驟做來連接Redis並被取得緩存的對象列表。
using(IRedisClient client = RedisClient) { var scheduleClient= client.GetTypedClient<Schedule>(); var schedules = scheduleClient.GetAll(); }
哪怕你緩存了很多對象這也是一個非常快速的操作。在Redis中緩存即用的對象是很好的想法,這免去了可能的業務處理操作(應用規則或其他過濾和格式化操作).
數據庫中重復提取的對象(很多時候是相同的)最好放到Redis中。通常我們要在倉庫中緩存的數據(更多細節請浏覽緩存倉庫模式cached repository pattern)也最好放到Redis中。這樣你就可以快速取得操作結果,大幅提升Web應用的整體性能。
注意scheduleClient將會暴露很多有關增加、添加、移除和使用列表、哈希等的函數。嘗試下探索更多。。。
你也可以設置你的Redis客戶端來看一下(不是用Glimpse-;))在添加monitor command的這種情況下發生了什麼(在我們開始時添加azul的同一個地方)。
在完整的反HelloWorld應用風格(我承認我是其中之一!)的勇士興奮的跳向天空之前,我還應該提醒一件事:從你的控制器連到你的數據庫(就是Redis!)不是個好主意,如果這對你來說很奇怪,我認為你需要讀一些關於設計和架構方面的東西。我不理解Microsoft的指導書讓用戶添加一個MVC項目,你就可以開始構建一耳光偉大的商業web應用了。因為不是這樣。
然而,下面是一個添加對象的例子,在這個情況下式一個調度器:
//domain object public class Schedule { public int Id {get; set;} public string Origin {get; set;} public string Destination {get; set;} } using(IRedisClient client = RedisClient) { var scheduleClient= client.GetTypedClient<Schedule>(); var schedule= new Schedule { Id= scheduleClient.GetNextSequence(), Origin ="Montreal", Destination = "Quebec" } var schedules = scheduleClient.Store(schedule); }
因為Redis是一個緩存服務,是可以通過設置一個超時時間讓輸入過期。你也可以通過移除那個超時來逆向這個過程。
這僅是一個關於Redis的簡介,給你提供一個提高web引用性能的方法啟示。在某些情況下,Redis可能會給你一些你的客戶或者老板沒有給你的,關於構建可靠軟件的激情的認可。
希望這能幫到一些人!