{"id":2097,"date":"2011-12-07T07:16:25","date_gmt":"2011-12-07T07:16:25","guid":{"rendered":"https:\/\/poiseddevelopers.com\/reality-tech\/?p=2097"},"modified":"2024-04-12T10:06:27","modified_gmt":"2024-04-12T10:06:27","slug":"rbs-remote-blob-storage-part-2","status":"publish","type":"post","link":"https:\/\/poiseddevelopers.com\/reality-tech\/rbs-remote-blob-storage-part-2\/","title":{"rendered":"RBS (Remote Blob Storage) part 2"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_65 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title \" >Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 eztoc-toggle-hide-by-default' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/poiseddevelopers.com\/reality-tech\/rbs-remote-blob-storage-part-2\/#Configure_SQL_Server\" title=\"Configure SQL Server\">Configure SQL Server<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/poiseddevelopers.com\/reality-tech\/rbs-remote-blob-storage-part-2\/#_Install_RBS_on_SharePoint_servers\" title=\"\u00a0Install RBS on SharePoint servers\">\u00a0Install RBS on SharePoint servers<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/poiseddevelopers.com\/reality-tech\/rbs-remote-blob-storage-part-2\/#Configuring_the_Blob_Store_in_SharePoint\" title=\"Configuring the Blob Store in SharePoint\">Configuring the Blob Store in SharePoint<\/a><\/li><\/ul><\/nav><\/div>\n<p>To get RBS going we are going to configure SQL Server, install the RBS libraries on the SharePoint servers, and configure it.<\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Configure_SQL_Server\"><\/span>Configure SQL Server<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>First enable FILESTREAM on the SQL Server instance by:<\/p>\n<ol>\n<li>Right-clicking SQL Server Properties, enable \u201cFILESTREAM for Transact-SQL access\u201d<\/li>\n<li>Enable \u201cFILESTREAM for file I\/O streaming access\u201d<\/li>\n<li>Enable \u201cAllow remote clients to have streaming access to FILESTREAM data\u201d<\/li>\n<li>Run the following SQL<\/li>\n<\/ol>\n<pre lang=\"php\">EXEC sp_configure filestream_access_level, 2\r\nRECONFIGURE\r\n<\/pre>\n<p>Next, we\u2019ll provivision a BLOB Store. You want a dedicated drive (not used by SQL Server binaries, temp, or the actual databases), and preferably cheaper storage. The BLOB Store needs to be configured for each database; otherwise the RBS configuration on the SharePoint fails (with a very unhelpful error).<\/p>\n<pre lang=\"php\">use [WSS_Content]   \r\n<\/pre>\n<p>&#8211;name of Content DB for which you are adding BLOB Store; you&#8217;ll undoubtedly have a number of DBs if you are doing RBS, so name them with a standard<\/p>\n<pre lang=\"php\">if not exists\r\n(select * from sys.symmetric_keys\r\nwhere name = N'##MS_DatabaseMasterKey##')\r\ncreate master key encryption by password = N'Admin Key Password !2#4'\r\n<\/pre>\n<p>&#8212; replace with your master password<\/p>\n<pre lang=\"php\">use [WSS_Content]\r\nif not exists\r\n(select groupname from sysfilegroups\r\nwhere groupname=N'RBSFilestreamProvider') \r\n<\/pre>\n<p>&#8212; SharePoint RBS has an undocumented bug\/limitation in that there can only one File Stream Provider, so use the same on e!<\/p>\n<pre lang=\"php\">alter database [WSS_Content]\r\nadd filegroup RBSFilestreamProvider contains filestream\r\nuse [WSS_Content]\r\nalter database [WSS_Content]\r\n<\/pre>\n<p>&#8212; set the location to your new cheaper storage dedicated Blob Storage location. You can create separate drives per DB<\/p>\n<pre lang=\"php\">add file (name = RBSFilestreamFile, filename = 'c:Blobstore') \r\nto filegroup RBSFilestreamProvider\r\n<\/pre>\n<p>Point to be aware of:<\/p>\n<p>Windows Firewall on the database server could generate an error. This is solved by disabling the firewall, or unblock remote debugging.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"_Install_RBS_on_SharePoint_servers\"><\/span>\u00a0Install RBS on SharePoint servers<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Before we get started, do yourself a favor, and snapshot or backup a server image, as well as the Content DBs. Installing RBS actually changes the Content DBs by adding a number of Tables and Stored Procedures. Make sure you use the x64 RBS drivers, and do not run the wizard to install by double-clicking the .MSI file. Microsoft reports that the wizard configures it suboptimally and is then unchangeable. Lastly, anything you ever install on SharePoint servers should be saved for reference, server reinstallation, DR, recovery, or even simply for adding another server to the farm. This includes any web part, feature, WSP, executable, but I digress\u2026<\/p>\n<p><strong>This is for the first install for the first database:<\/strong><\/p>\n<pre lang=\"php\">msiexec \/qn \/lvx* rbs_install_log.txt \/i RBS.msi TRUSTSERVERCERTIFICATE=true FILEGROUP=PRIMARY DBNAME=\"Content_Intranet_IT\" DBINSTANCE=\"SQL Server Instance Name\" FILES\r\nAMFILEGROUP=RBSFilestreamProvider FILESTREAMSTORENAME=[TheNameOfTheFileStream]\r\n<\/pre>\n<p><strong>This is for subsequent\u00a0databases:<\/strong><br \/>\nThe key here is the name of the File Stream Store cannot change between databases. This is the RBS limitation mentioned earlier. For each DB, it creates a set of Tables and Stored Procedures.<\/p>\n<pre lang=\"php\">msiexec \/qn \/i rbs.msi REMOTEBLOBENABLE=1 FILESTREAMPROVIDERENABLE=1 DBNAME=\"your content db name\" FILESTREAMSTORENAME=[TheNameOfTheFileStream] ADDLOCAL=EnableRBS,FilestreamRunScript DBINSTANCE=\"SQL Server Instance Name\"\r\n<\/pre>\n<p>he next challenge is determining if the installation worked. The command returns the command prompt instantly; even though it is running in the background. It runs for a minute or so typically. The logs are actually quite unclear. Microsoft says to scroll to the end of the file and on the last 20 lines find \u201cProduct: SQL Remote Blob Storage \u2013 Installation completed successfully\u201c. Another way to tell is to look at the size of the logfile. A failed install has a logfile has around 500kb and does not have the above text near the end of the file, while a successful install has a logfile of 1.4MB if the database was RBS enabled as part of the RBS install. One last thing to check is that the RBS tables were created in the database. To do that, fire up SQL Studio, open the content database, and look at the end of the list of tables. If RBS is configured for the database, you\u2019ll see roughly 20 tables starting with \u201crbs_\u201d. These tables track references to the Blob Store, as well as configuration and housekeeping such as the history and deleted items for managing the lazy delete cleanup process we\u2019ll be discussing later on configuring and running the \u201cMaintainer\u201d.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Configuring_the_Blob_Store_in_SharePoint\"><\/span>Configuring the Blob Store in SharePoint<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>At this point we might think we are done, but there\u2019s more to do; nothing is being stored yet in the FILESTREAM Blob Store.\u00a0 SharePoint will continue to blindly store all files in the database.\u00a0 Here are the simple steps to take in PowerShell (ensure the SharePoint snap-in is loaded):<\/p>\n<p># Provide your content DB name using the name of the Content DB, or if there&#8217;s only one Content DB for a web app, you can get it by identifying the web app<\/p>\n<pre lang=\"php\">$cdb=Get-SPContentDatabase -identity Content_DB_Use_Your_Name  \r\n$cdb = Get-SPContentDatabase \u2013WebApplication &lt;a_href=\"htt mysite\"=\"\"&gt;htt p:\/\/MySite\r\n<\/pre>\n<p># This grabs the Blog Storage Object. if you type &#8220;$rbs&#8221; it will show the status, which initially is not enabled<\/p>\n<pre lang=\"php\">$rbs = $cdb.RemoteBlobStorageSettings\r\n$rbs.GetProviderNames()\r\n$rbs.Installed()  #this confirms it is installed correctly\r\n$rbs.Enable()   # This is the key; it enables the Blob store\r\n$rbs.SetActiveProviderName($rbs.GetProviderNames()[0])\r\n<\/pre>\n<p># Setting the active provider is required; there&#8217;s only one, at index 0<\/p>\n<pre lang=\"php\">$rbs.MinimumBlobStorageSize =500kb\r\n<\/pre>\n<p># this is the minimum size of a file to be sent to the Blob Store; anything smaller is kept in the Content DB.<\/p>\n<pre lang=\"php\">$rbs.Migrate()\r\n<\/pre>\n<p># this forces content into Blob Store from the Content DB, or moves content out of the Blob Store and back to the Content DB; based on the minimumBlobStorageSize<\/p>\n<pre lang=\"php\">$rbs.update()\r\n$cdb.update()\r\n<\/pre>\n<p># both updates are absolutely required for the minimumBlobStorageSize size to &#8220;stick&#8221;. Existing documentation neglects this point.<br \/>\nSetting the MinimumBlobStorageSize is key. Setting it aggressively low results in a smaller Content DB, but relies more heavily on the speed of the Blob Store. A range of 100kb to 1mb is reasonable. You can experiment using different values, doing an $rbs.migrate() and testing. Note the Blob Store can grow rapidly due to the design, where overwritten files in SharePoint are never overwritten in the Blob Store; instead new files are created. A subsequent cleanup process needs to be configured and run called the \u201cMaintainer\u201d, but that\u2019s tomorrow\u2019s blog.<br \/>\nCheck out <a href=\"https:\/\/poiseddevelopers.com\/reality-tech\/rbs-remote-blob-storage-part-3\/\" style=\"color:#1f6799\" target=\"_blank\" rel=\"noopener\">RBS Part 3<\/a><br \/>\n[\/av_textblock]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To get RBS going we are going to configure SQL Server, install the RBS libraries on the SharePoint servers, and configure it. &nbsp; Configure SQL Server First enable FILESTREAM on the SQL Server instance by: Right-clicking SQL Server Properties, enable \u201cFILESTREAM for Transact-SQL access\u201d Enable \u201cFILESTREAM for file I\/O streaming access\u201d Enable \u201cAllow remote clients [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":2098,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[40],"tags":[],"class_list":["post-2097","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-rbs"],"acf":[],"_links":{"self":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2097","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/comments?post=2097"}],"version-history":[{"count":9,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2097\/revisions"}],"predecessor-version":[{"id":3029,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2097\/revisions\/3029"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/media\/2098"}],"wp:attachment":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/media?parent=2097"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/categories?post=2097"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/tags?post=2097"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}