1: Scrimping on SharePoint's RAM or Hard Disk Space
A poor, defenseless SharePoint server working as
hard as it can to keep users happy, but having its
hands tied because of limited resources. This situation is usually a
casualty of aggressive virtualization. Virtualization itself isn't bad,
but it
must be done intelligently and without sacrificing SharePoint's ability
to do its job.
If SharePoint finds itself starved for RAM, it starts shutting off
functionality so that it can fit into the available space. It also
caches less in
the web application pools and recycles those pools more often. Less
caching and more recycles result in a degraded end-user experience, as
SharePoint
must compile the same ASP.NET code over and over. And no one likes
unhappy users, not even their mothers.
The solution to this particular issue is easy: Add RAM. Microsoft has
published the hardware requirements for SharePoint 2010 in the TechNet
article "
Hardware and software requirements (SharePoint Server 2010)."
These requirements state that at the very least, each SharePoint 2010
production server should have
8GB of RAM and a C drive with at least 80GB. In many cases, that won't
be enough. If your servers are in production, you can watch their memory
utilization to see whether they use the entire 8GB of RAM. If so, they
could use more. If your servers are not yet in production, you can use a
variety
of load-testing tools to simulate your intended load and see how the
servers hold up. For example, you can download the
Microsoft Load Testing Kit,
part of the SharePoint Administration Toolkit.
As for your C drive, SharePoint itself doesn't need much space, but
Windows does. After all, your server has several years of Windows
patches to look
forward to. While you're adding drive space to your machine, consider
adding a secondary drive as well. This drive is a great place to store
all the
files that you use when you install SharePoint. All the third-party
installation files can go there too. You can also have SharePoint put
its log and
Search index files on this drive. This approach takes some pressure off
the C drive. Happy C drive and happy end users equal a happy SharePoint
server
administrator.
2: Using Virtualized Microsoft SQL Server
Virtualization isn't bad. But virtualization
allows administrators to make mistakes on a much grander scale. Take
virtualizing
SQL Server. In the context of SharePoint, this process can be especially
painful. The main mistake I see when virtualizing SQL Server is
overcommitting
the host, be it through RAM, CPU, or drive space. Because everything in
SharePoint is stored in SQL Server, if SQL Server is slow, SharePoint is
slow.
The obvious solution is to move SQL Server to a physical box, on which
it doesn't need to share resources. Moving SharePoint's SQL Server
instance is
easy, thanks to aliases. This process outlined with pictures, at
www.toddklindt.com/sqlalias.
If you can't get a physical SQL Server box, then at the very least
ensure that your virtualized SQL Server instance has a fighting chance.
First, make sure that
its virtual drives aren't thin provisioned. I/O is one of the areas in
which virtualized SQL Server struggles the most, and thin-provisioned
drives exacerbate
that problem. Also try to put the SQL Server guests' virtual drives on
their own spindles on the host. Doing so should improve I/O by
preventing SQL
Server from fighting other guests for time with the drives. Finally, you
shouldn't allow the virtualization host to overcommit its RAM. If the
host must swap
to meet its RAM obligations, then it's slowing down SQL Server.
Brent Ozar has recorded a
brilliant video on how best to virtualize SQL. Go get
some wine and pizza, invite your fellow SharePoint admins, dim the lights, and watch that video. You'll learn a lot.
3: Using the Farm Configuration Wizard
Using the Farm Configuration Wizard was a pretty common mistake when
SharePoint 2010 first came out but thankfully has diminished as our
familiarization with SharePoint 2010 has increased. The wizard's list of
atrocities is long, so I'll just cover some of the better known ones.
First, and maybe most heinous, is that all the databases that the wizard
creates have nasty globally unique identifiers (GUIDs) at the end of
their names. The wizard also creates a content web app, at
http://servername, that just doesn't scale well. To add insult to
injury, the wizard creates your My Site host on that same web app, at
http://servername/my. Finally, the wizard encourages you to create
service applications that you might not actually use. It's tough to
resist the siren song of those check boxes, I know.
The Farm Configuration wizard leaves its dirty handprints all over
SharePoint, and it can be a challenge to clean up all of them. However, a
few places
can be easily fixed. Start with your web apps. Create a web app for My
Site and give it a Fully Qualified Domain Name (FQDN), such as
mysites.company.com. Create a My Site host at the web app's root. Use
the Windows PowerShell cmdlet Move-SPSite to move any My Site to one
content
database, and then attach that content database to your new web app.
You'll also need to adjust your User Profile Service and tell it about
your new My
Site location.
Next, clean up your service applications. Go through your list of
service applications and delete any that you aren't using. You gain no
benefit from
having a service application that you aren't going to use for another
six months. After you've deleted unnecessary service applications, stop
the
associated service instances (also called
services on server) that power them. If possible, remove the GUIDs from the service application database
names. The technique for completing these tasks varies among service application; the Microsoft article "
Rename or Move Service Application Databases (SharePoint Server 2010)" has directions for all the service applications. Of course, take good
backups before doing any of this.
4: Using an Incorrect URL when Creating a Content Web App
Like any relationship, SharePoint and Microsoft IIS have communication problems from time to time. Web app creation is one of those times. SharePoint doesn't tell IIS about changes that you might make to a web app after it is created. For instance, if you create an Alternate Access Mapping (AAM) for a web app in Central Administration, you still need to go into IIS and add the host header for the new address.
The issue is compounded when SharePoint farms that you never thought would need to be accessible from the Internet suddenly need to be accessible from the Internet. Budding SharePoint administrators commonly give their web apps short URLs, such as http://portal, to save users some typing. Of course, that URL doesn't route across the Internet, so the web app needs a fully qualified URL added to its stable of AAMs. Not only is this new URL not written to the IIS host headers, but it's also missing from all the alerts, workflows, and anything else that saves URLs -- all those items have the old URL hard-coded in. Because SharePoint didn't write any additional URLs to IIS when they were created, it won't write them to any new SharePoint servers that are added to the farm. Nor will SharePoint write these changes to IIS if the Microsoft SharePoint Foundation Web Application service instance is stopped and started.
This issue might not seem like a big deal, but it has bitten many people at the worst possible time: during an outage. In a few cases, administrators have lost or needed to rebuild a SharePoint server and forgotten about the host headers that they put in manually months earlier. SharePoint is up and going, but when browsing to SharePoint, end users get the blue IIS 7 splash page instead of the SharePoint page that they were expecting. Again, unhappy users usually mean unhappy administrators.
Because SharePoint writes host headers only when a web app is created, you can't fix problematic web apps. You'll need to recreate them. That's good news and bad news. The good news is that you won't lose any of the content that your users worked so hard to create. The bad news is that you will lose all the settings that you worked so hard to create.
The first step is to make notes of all your web app settings. In most cases, there won't be many, and you'll be familiar with any changes that you made. Then, detach the content databases from your web app. Keep them safe; you're going to need them. Next, make a copy of the web.config file for that web application. Some settings, such as forms-based authentication (FBA) and BLOB cache settings, are in that file. Finally, go into Central Administration and delete the web app. Tell SharePoint to delete the extra stuff. The scary part is over.
Now, recreate the web app, but do it right this time. First, enter the correct, fully qualified URL in the Host Header box. Do your end users a favor, and put the web app on port 80, as Figure 1 shows. Under the Security Configuration settings, accept all the defaults, even if you're going to use Kerberos or SSL. You can change those settings later, and you want to make sure that the web app works correctly before you apply fancy security settings. Doing so helps in any troubleshooting that you might need to do. Under the Application Pool settings, pick an existing application pool.
It is important to give your content databases distinct names. You
should be able to look at a content database name and know exactly which
web app
that database goes with. This is another one of those things that
doesn't usually seem important but is priceless in a disaster-recovery
situation. If
the content databases that you detached from the web app before you
deleted it didn't have such names, then take this opportunity to right
that wrong
when you recreate the web app. Give the new content database a good
name, then use the PowerShell cmdlet Move-SPSite to move the site
collections to
that new database. If your content database already has a good name,
enter it during the creation of the new web app. If you had multiple
content
databases, attach the rest after the web app is created.
After the web app is created, you can tweak settings as needed. Most
settings can be changed in Central Administration. If you made any
changes to the
web.config file of the original web app, now is the time to copy those
changes to the newly created web.config file. You can use a program such
as
Notepad++ to compare the two files. You should now have a well-created web application that you can trust in times of crisis.
5: Running Web Apps or Service Apps in Separate App Pools
Web apps and service applications run inside of an
application pool, which is a W3WP.exe process that runs on your server.
Unless you have reason to do
otherwise, you should run all SharePoint web apps inside one application
pool; the same goes for the service applications. Running each web app
in its own
application pool makes inefficient use of the server's memory. Each
application pool has a minimum overhead of more than 100MB, and its
memory
footprint increases as it caches content that's rendered frequently.
Figure 2 shows multiple W3WP.exe processes running as sp_webapps, the
result of
web apps running in separate application pools. We've all experienced
SharePoint slowing first thing in the morning because the app pools
recycle
overnight and need to warm up and cache that content again. Well,
multiple application pools mean that the same content is cached multiple
times. Most
users are impatient. I'm sure that studies would show that they spend
the time waiting for SharePoint to respond by thinking of ways to punish
us for
SharePoint's poor performance.
For service applications, this problem is easy to fix. First, make sure that you have a good service application pool to use. I recommend calling this pool Default SharePoint Service App Pool so that it floats to the top of all your drop-down lists. Use a dedicated sp_serviceapps account for the pool's identity. Most service applications allow you to assign them to a new service application pool by modifying their properties in Central Administration. If the option is unavailable there, look for it in PowerShell.
Web applications are a tougher matter. There's no easy, out-of-the-box way to change the application pool that a web app is using. Fortunately, we have PowerShell at our disposal.
6: Using One Account for Everything
Security is complicated, and SharePoint doesn't
necessarily make it any easier. Using just one account -- maybe even the
coveted Domain Administrator
account -- is so easy. We've all done it, even though it's a bad idea.
When you use an existing account, you open up SharePoint to several
security
issues. Anyone who knows the account password can do anything in
SharePoint, so you can't separate duties. You also lose the ability to
audit who made
which changes. And if that common account password is compromised or
needs to be changed, you jeopardize SharePoint's uptime as well. Even if
you use
one dedicated account for SharePoint, you leave yourself vulnerable to
attack. If that account is compromised via a security exploit, the bad
guys will
have access to everything in SharePoint.
To fix this mistake, start by creating the accounts. Add the sp_webapps and sp_serviceapps accounts as managed accounts. Use the techniques that describe in Mistake No 5 to fix your web app and service application accounts. You can change the default content access account for the Search service application at the Search Service Application page. Under Central Administration, Security, Configure Service Accounts, you can change the accounts that other processes use as well. (You can even change the Farm Account there. I've done so in test environments but haven't been brave enough to do it in production.) If you're using the User Profile Service, make sure that your new sp_userprofile account has the correct permissions in Active Directory (AD), and recreate your AD connection in the User Profile Service.
7: Keeping Default SharePoint Database Settings
When SharePoint creates its multitudes of databases, it makes some bad
assumptions. Take the autogrow settings: The database files grow by 1MB
at a
chunk, almost ensuring that they're going to autogrow with every upload.
Not only does this slow down SQL Server (which slows down SharePoint),
but it
also results in database files that are spread all over your drives in
itty-bitty 1MB chunks.
SharePoint also creates most of its databases, notably the Config and
Content databases, with the recovery model set to Full. Although this is
great if
you want to recover data, you must manage the process correctly or those
sneaky .ldf files will slowly, methodically fill your hard disk. If you
think
users get upset when SharePoint is slow because of fragmented databases,
you should see how angry they get when SharePoint stops completely
because the
SQL Server drives are full.
To fix this mistake, set your databases' autogrow settings in such a way
that they don't need to grow frequently. For most farms, I recommend
changing
the 1MB autogrow to something like 500MB or 1GB. Autogrow should also be
a last resort. Someone, either the SharePoint administrator or a
dedicated
DBA, should pregrow your databases so that autogrow is unnecessary.
Your recovery model setting needs to be consistent with your disaster
recovery plans. If you need your transaction logs, make sure you're
performing
routine log backups to keep those .ldf files in check. If you don't need
your transaction logs, then consider switching your databases to the
simple
recovery model. Doing so will keep your .ldf files from swelling up like
a nasty bee sting.
8: Not Enabling BLOB Caching
We all want
SharePoint to get files to the users as quickly as possible. However,
more often than not, I see SharePoint farms without BLOB caching
enabled. BLOB
caching is one of the easiest and least expensive ways to improve
SharePoint performance. Not only does it help to get files to users more
quickly, but
it also eases the burden on SQL Server. Everybody wins.
This might be the easiest solution so far: Enable BLOB caching, of
course! BLOB caching is actually a function of IIS; SharePoint just
takes advantage
of it. Therefore, to enable BLOB caching requires a change to each web
app's web.config file on each server. Fortunately, the setting already
exists
and just needs to be enabled. By default, the web.config files are in a
directory under C:\inetpub\wwwroot\wss\virtualdirectories. Each web app
has a
directory and a web.config file. Open one of these files and look for
the following line:
<BlobCache location="C:\blobcache\14"
path="\.(gif|jpg|jpeg|jpe|jfif|
bmp|dib|tif|tiff|ico|png|wdp|hdp|css|js|asf|avi|flv|m4v|mov|mp3|mp4|
mpeg|mpg|rm|rmvb|wma|wmv)$" maxSize="10"
enabled="false" />
To enable BLOB caching, replace "false" with "true" and save the
web.config file. You should also move the file to a directory on a drive
other than
the C drive. The maxSize parameter is measured in gigabytes, with a
default of 10GB. If the space is available, you might want to increase
this size.
If editing this file in Notepad on all your servers isn't your idea of
fun, you can use PowerShell to automate the process. You still need to
perform
the process on each server, but using PowerShell is quicker and reduces
the chances of a mistake.
9: Not Installing a PDF iFilter
Most organizations have a tremendous number of PDF files in their
SharePoint farms, and those files represent a wealth of information. End
users want
to be able to discover that information by using SharePoint Search.
Getting users excited about SharePoint Search is a great way to get them
excited about SharePoint in general.
Installing a PDF iFilter is fairly easy. Adobe has a free PDF iFilter
that you can install. You can find the download link and detailed
installation
instructions in the Microsoft article "
SharePoint 2010 - Configuring Adobe PDF iFilter 9 for 64-bit platforms."
You need to install the iFilter only on those SharePoint servers that
run the Search Index role,
although installing it on the rest of your SharePoint servers doesn't
hurt. If you have a large farm and want to reduce the time needed to
index your PDF
files, you can use the
PDF iFilter from Foxit. This product has better performance than the Adobe iFilter but isn't free.
10: Not Pointing Your SharePoint Servers at Themselves
When SharePoint works, it is magnificent. When it doesn't work, it can
be a nightmare to fix. For this reason, anything you can do to ease
troubleshooting is time well spent. To that end, I make sure that every
server in the SharePoint farm points to itself for all web apps. If I
get
sporadic reports about SharePoint not responding, I can easily use RDP
to log in to each server and try to pull up SharePoint. If this attempt
works,
then I know that the server is working. If SharePoint does not come up,
then I know in exactly which Microsoft User Location Server (ULS) logs
to look
for the relevant errors. No worrying about which web front end the load
balancer sent my request to. The quicker you get to the correct log
files, the
quicker the problem is resolved.
Pointing your Search indexer at itself has another advantage: It
improves performance for your end users. If you don't point your Search
server at
itself, then when it starts to perform a crawl, it lets DNS do its work
and then starts crawling whichever web front end DNS points it to. That
server
is most likely the same one that is sending pages to your end users.
Making the server do double-duty means that everyone waits longer.
Pointing the
Search server at itself means that your web front end doesn't need to
handle that traffic and can get back to doing its #1 job: keeping users
happy.
There is a simple fix for this mistake: Open the hosts file
(C:\windows\system32\drivers\etc\hosts) on each SharePoint box, and add
all the URLs that
SharePoint knows about. Point those URLs to 127.0.0.1, which translates
to "this computer." Figure 3 shows how this file looks in a typical
SharePoint
environment.