一个应用程序的大型实例,还是许多中型实例?
我们为一位客户编写的 Web 应用程序将被产品化并出售给数十家公司,我们将负责托管。
我可以使用一些指导来了解为每个客户推出单独的实例与使用单个(或极少数)多租户实例的优缺点。
首先,随着我们的发展,我将必须为每个新客户推出一个单独的应用程序实例(他们一次会上线一个),因为这是唯一的直接选择。我认为就维护而言,这不会很好地扩展 - 一旦存在超过 4 或 5 个实例,推出更改将变得非常乏味,并且可能容易出错。除非我们以某种方式实现自动化。
此外,如果人们需要定制,单实例哲学似乎可能会导致一堆分叉。如果能避免这种情况就好了。
那么您在这方面有什么经验呢?
额外问题 1: 10 个每个有 200 万条记录的 SQL Server 与一个有 2000 万条记录的大型 SQL Server 之间的性能差异是什么?假设它们都在一张表中,我们主要对单个记录进行插入和选择。有时,选择位于索引 varchar(12) 或日期字段上。
额外问题#2:我想为了避免分叉,我们必须使自定义可配置,或者构建一个插件架构。但是,这可能会增加进行定制的成本,而且我不想成为那些需要一周时间调整文本框大小的商店之一,而且我不想过度投资基础设施。对此有什么想法吗?
规模详细信息
每个客户都将拥有大量数据 - 最多几百万条记录。
并发用户数量非常少,每个客户只有几个,再加上我们这边的少数内部代表。
目前还不清楚每个客户是否都需要定制,但我想说其中一些可能会需要,也许其中一些变化是其他客户不希望看到的。
A web application we wrote intended for one customer is going to be product-ized and sold to dozens of companies, and we will be doing the hosting.
I could use some guidance about the pros and cons of rolling out a seperate instance for each customer versus going with a single (or very small number of) multi-tenant instances.
At first, as we ramp up, I will have to roll out a seperate instance of the application for each new customer (they will come online one at a time) because it's the only immediate option. I imagine this won't scale very well as far as maintenance goes - rolling out changes will become very tedious and possibly error-prone once there are more than 4 or 5 instances out there. Unless we automate that somehow.
Also, the single-instance philosophy seems like it might lead to a bunch of forks if people need customizations. And it would be nice to avoid that.
So what has your experience been with this?
Bonus question #1: What's the performance difference between 10 SQL Servers with 2m records each versus one huge one with 20m? Let's say they are all in one table and we're mainly doing inserts and selects on single records. Sometimes the selects are on an indexed varchar(12) or date field.
Bonus Question #2: I imagine that to avoid forking, we would have to make the customizations configurable, or build a plug-in architecture. However, that might increase the cost of doing customizations, and I don't want to be one of those shops that takes a week to resize a textbox, and I don't want to over-invest in infrastructure. Any thoughts on that?
Scale Details
Each customer will have a decent amount of data -- up to a few million records.
There will be a very small number of concurrent users, only a few per customer, plus a handful of internal reps on our end.
It's unclear whether each customer will require customizations, but I would say some of them probably will, and maybe some of those changes will be things that other customers will not want to see.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
当面临类似的挑战时,我们做了以下事情:
我们有一个包含多个 sql 服务器的代码库。我们确实维护多个具有相同代码库副本的 iis 服务器。我们可以自由地将客户端从一个 SQL Server 迁移到另一个 SQL Server,以最大限度地提高性能。
如果客户有足够的资金,我们将把它们安装在他们自己的服务器上,并为他们维护一个单独的 iis 服务器。这适应了最大的客户,他们每月支付更多的钱(多出十倍的钱)。但是,我们不会为他们提供单独的代码库。如果他们需要一个 mod,我们会在每个客户端上使其可见(参见 #3)
自定义编程通常会产生可配置的选项。即使那些付钱给我们拥有自己的服务器的人也能得到相同版本的代码。有时它就像代码中的一个子句一样简单,“如果客户=“ourbigcustomer,则打开此选项”。是的,这是笨拙的硬编码,但如果客户有足够的钱,那对我来说没问题。
我没有完全从你的问题中得到答案:你是否想将不同客户的数据混合到一个大数据库中。我们的规则是我们从不这样做(从不)。这是我们做过的最明智的选择之一。它使数据操作的风险大大降低,数据恢复也更容易。
when faced with a similar challenge, here's what we did:
we have one code base with multiple sql servers. we do maintain multiple iis servers with copies of the same code base. we are free to move clients around from sql server to sql server to maximize performance.
if a customer has the $ for it, we will install them on their own server and maintain a separate iis server for them. this accommodates the largest customers for whom paying much more money every month (10 fold more money). we do not, however, give them a separate code base. if they need a mod, we make it visible on a per client basis (see #3)
custom programming usually results in a configurable option. even the people who pay us to have their own server get the same version of the code. sometimes its as simple as a clause in the code that says "if the customer = "ourbigcustomer then turn on this option". yes, that's kludgy hard-coding, but if the customer has enough money, that is fine with me.
i didn't quite get from your question whether you wanted to mix different customer's data into one big database .. our rule is we never do that (never ever). it is one of the wisest choices we ever made. it makes data manipulation much less risky and restores of data easier.
我认为您的两个选择都没有充分的理由。我认为真正的答案位于中间的某个地方:拥有多个实例,每个实例托管多个客户端。
这增加了另一层自动化处理,但这意味着您可以保持托管便宜(您不需要很快出去购买 Cray)并且(希望)这种心态意味着您可以相当轻松地进行故障转移备份。
但我们不要超前...我们正在谈论一个网络应用程序,对吧?在不同的机器上获取数据库和 aspnet。集群您的数据库,您将在各种前端场景中度过更愉快的时光。您还可以升级最先耗尽烟气的区域。
听起来,您最终将得到一个集群数据库,超过一半(如果不是一打数据库机器的话),并且只有几个前端框。
至于定制,你已经搞定了。您要么提供一组完全由数据库托管的可编辑模板,要么必须自定义 who 实例。我完全赞成第一。这是一项繁重的工作(没有太多回报),但这是非常值得的,因为您只需要在(您会!)进行升级时更改核心代码。 搜索一百个客户的自定义实例以确保它们安全升级将会杀死开发人员!模板就是答案。至少,您可以轻松地允许自定义 CSS(但他们需要了解其知识的人)。
编辑:我看过几篇关于一体化方法的帖子。将实例拆分到多台计算机上可以使您免受以下几件事的影响:
如果您引入了测试中未捕获的错误,则只有少数客户端会同时受到影响
硬件发生故障 。一台大型服务器崩溃会立刻惹恼很多人。拥有一台故障转移大型服务器非常昂贵。每三到四台正在运行的服务器配备一个备用故障转移盒会便宜得多,而且烦恼的人也更少。
可以在每个客户端的基础上平衡各个盒子之间的性能,因此您可以将一些轻度使用的客户端与重型客户端放在一起,或者只用一些中等使用的客户端填充一个盒子,等等。
同样的想法,使用高峰或其他放缓只会影响同一盒子上的客户端。当然,这对于数据库来说并不意味着相同,但是当您到达那里时,您可以将其拆分为一个集群。
I don't see a good reason for either of your two options. I think the real answer lies somewhere in the middle: having multiple instances, each hosting multiple clients.
This adds another layer of automation processing, but it means you can keep the hosting cheap (you won't need to go out and buy a Cray any time soon) and (hopefully) this sort of mentality means you could do failover backups fairly easily.
But let's not get ahead of ourselves... We're talking about a webapp, right? Get your database(s) and aspnet on different machines. Cluster your databases and you'll have a much happier time playing around with various front-end scenarios. You'll also be able to upscale whichever area runs out of puff first.
By the sounds of it, you'll end up with one clustered database over half if not a full dozen database machines and only a couple of front-end boxes.
As for customisations, you've nailed it. You either provide a completely database-hosted set of editable templates or you have to customise who instances. I'm all for the first. It's a lot of work (without much in return) but it's well worth it as you should only need to change the core code when (you will!) you do upgrades. Hunting through a hundred customers' custom instances to make sure they upgrade safely will kill a developer! Template are the answer. At the very very least, you could allow custom CSS without much pain (but they'd need somebody who knew their stuff).
Edit: I've seen a couple of posts going for the all-in-one method. Splitting the instances over multiple machines insulates you from a couple of things:
If you introduce a bug not caught in testing, only a few clients are effected at once
Hardware fails. Having one mega-server fall over will annoy a lot of people at once. Having a failover mega-server is massively expensive. Having a spare failover box per three or four running servers is much cheaper and annoys fewer people.
Performance can be balanced between boxes on a client-by-client basis, so you can put a few light-use clients with a heavy client, or just fill a box with a few medium-use clients, etc.
On the same idea, usage spikes or other slowdowns only effect clients on the same box. Of course this doesn't mean the same for the database, but you can split that up into a cluster of clusters when you get there.
单个实例的一大优势将是随着每个客户需求的增加而扩展。例如,如果您在一台服务器上运行,而一位客户突然需要更高的性能,那么您就会不知所措。但如果他们都是个人,那么将该客户转移到闪亮的新服务器就相对容易了。
最大的缺点是单独管理所有实例。 (无论它们是否都在同一台服务器上运行)。
无论如何,您应该只拥有一个代码库实例。定制应该全部通过插件和配置来控制。前端自然应该与内容分开。尽管进行更改的成本可能会更高,但我确信您可以为其他客户提供的功能(这只是您被要求进行的定制)所带来的好处将会得到回报。也就是说,管理单个代码库比管理多个代码库要容易得多。
The big advantage of individual instances will be scaling out as each customer's demand increases. For example if you're running on a single server and one customer suddenly needs more preformance you're stuffed. But if they're all individual then moving that customer to a shiny new server is relatively easy.
The big disadvantage will be in managing the instances all individually. (regardless of whether they're all running on the same server or not).
Regardless you should only ever have one instance of the codebase. And customisation should all be controlled through plugins and configuration. Front end should naturally be seperate from content. Although the cost of making a change may be higher, the benefit in terms of features you can offer your other customers (which will just be customisations you've been asked to do) will pay off I'm sure. Which is to say nothing as to how much easier it'll be to manage a single codebase, as opposed to several.
我强烈建议使用贵公司托管的单一实例。这样做具有以下优点:
和数据库进行更改和
更新。
它运行的硬件。
你已经把它一劳永逸地解决了
顾客。
设计以更好地支持客户
特定代码并避免分叉。
可以扩展和扩展您的
服务器见面
性能/响应能力
要求。
不能被篡改
“好奇”的顾客。
我不得不说,应用程序在哪里运行比有多少个单独的实例更重要。
当然,由于支持/维护开销,维护多个单独的实例并不理想,但如果这些应用程序。全部都在您控制的服务器上,比需要远程/物理访问不同的客户网络和服务器要容易得多。
Joel Spolsky 在 StackOverflow podcast 67 上也谈到了这一点。
记录相对来说并不是一个庞大的SQL Server数据库。单个配置良好的 SQL Server 可以轻松处理这种大小。然而,更重要的是对数据库的并发访问数量。然而,您说每个客户只有几个用户,因此在并发级别增长之前不太可能对您造成影响。
I would strongly advise going with the single instance hosted by your company. This has the following advantages:
and databases to make changes and
updates.
hardware it is running on.
you have fixed it once for all
customers.
design to better support customer
specific code and avoid forking.
can scale-up and scale-out your
servers to meet
performance/responsiveness
requirements.
cannot be tampered with by
"inquistive" customers.
I would have to say it is almost more important where your application is running as opposed to how many separate instances there are of it.
Sure, maintaining multiple separate instances is not ideal due to the support/maintenance overhead, but if these apps. are all on servers you control, life is much easier then needing remote/ physical access to different customers networks and servers.
Joel Spolsky also talks about exactly this on StackOverflow podcast 67.
20 million records relatively speaking is not a huge SQL Server database. A single well provisioned SQL Server could handle this size comfortably. More important however is the number of concurrent accesses to the database. However you say that there will be only a few users per customer so is unlikely to hit you until the level of concurrency grows.
以上都是很好的观点,但您遗漏了两个关键问题。提供的服务价格是多少?您最终需要支持多少客户(数量级)(即市场规模)? 3 年后,您最多会拥有 10 个客户,每个客户每年向您支付 500,000 美元,还是 500 个客户,每个客户每年向您支付 10,000 美元?对于一小部分高付费高级客户来说,单独部署的优势是显而易见的,而较低的价格和更大的客户群需要共享解决方案(la Oli 的评论)是最好的选择。或者使用云平台,尽管我只阅读了炒作并进行了修改,而不是在现场部署它。
附加问题 1:表布局、索引、读/写次数、存储过程的效率和复杂性(您正在使用过程或至少使用准备好的语句,对吗?)都比存储过程中的物理记录数量重要得多。数据库到一个点。除此之外,您可能会发现自己需要为每个客户或一组客户提供单独的 SQL Server 实例,这又取决于我上面提出的一些问题。
额外问题 2:在这种情况下,将时间投入到模板和插件架构的设计中至关重要,而且您需要尽早完成。一旦您开始为付费客户定制代码,您可能就没有时间去做正确的事情。这一点怎么强调都不为过。模板和管理工具可让您快速深入地访问产品中数据驱动的更改,这将为您节省大量时间。随着您的公司/集团的扩展,您可以添加更少的技术人员,这些技术人员可以是“产品专家”,可以执行 90% 的定制和维护,从而释放您的核心以继续开发或转向其他项目。最后,不要在此规划过程中忽视您的数据层。拥有(几乎)不可变的存储过程和表的核心数据层非常重要,使用良好的命名约定清楚地划分自定义表和存储过程。
祝你好运,如果您需要更具体的建议,请随时提供更多详细信息。
All of the above are good points but you are missing two key questions. What price point is the service offered at and how many customers (order of magnitude) will you ultimately have to support (ie market size)? In 3 years will you have a maximum of 10 customers each of which will pay you $500,000 per year or 500 customers each paying you $10,000 per year? For a small set of high paying premium customers the advantages of individual deployments is clear, whereas the lower prices and larger customer bases demand a shared solution (a la Oli's comment) is the best way to go. Or go with a cloud platform, although I've only read the hype and tinkered rather than deployed that in the field.
Bonus Question 1: table layout, indexing, number of reads / writes, efficiency and complexity of stored procedures (you are using procs or at least prepared statements, right?) all matter a heck of a lot more than the number of physical records in the database to a point. Beyond that you will likely find yourself needing to either provide individual SQL Server instances for each customer or for a pool of customers, once again depending on some of the questions I raised above.
Bonus Question 2: Putting the time into your design for templating and a plugin architecture is essential in this situation and you need to do it sooner rather than later. Once you're in the grind of customizing code for paying customers you will likely not have the time to do it right. This point cannot be stressed enough. Templates and admin tools that give you quick and deep access to data-driven changes in your product will save you a lot of time down the road. As your company / group expands you can then add less technical staff that can be "product experts" who can perform 90% of customizations and maintenance, freeing up your core to continue development or move on to other projects. Finally, don't neglect your data tier in this planning process. Having a core data tier of (almost) immutable stored procs and tables is very important, with custom tables and stored procs clearly demarcated using a good naming convention.
Good luck, feel free to provide more details if you'd like more specific suggestions.
根据此处收到的一些建议,我们最终实现了应用程序的整体多租户版本。
我很高兴我们做到了。当它完成时,我们已经有了 3 或 4 个代码库分支(主要是自定义皮肤和我们没有 n 级支持的东西,但也有一些实际功能),而且它只会变得更加疯狂。
我们推出了多租户版本,并成功地将所有内容合并在一起。最终需要考虑很多事情,需要跟踪很多事情,但我们的客户甚至不知道他们已经转移到新系统。
我想说,实际的客户迁移有点困难。我一开始以为我们可以在后端手动完成这项工作,但最终我不得不编写一些相当复杂的脚本来完成工作。身份列太多了,当您导入实时生产系统时,您不可能暂时关闭约束。
Based on some of the advice received here, we did end up implementing a monolithic multi-tenant version of our application.
I'm glad we did. By the time it was done, we had 3 or 4 forks of the code base (mainly custom skins and things we didn't have n-level support for, but also some actual features), and it was only getting crazier.
We got the multi-tenant version up and successfully folded everything in. There ended up being a lot to think about and a lot to keep track of, but our customers never even knew they had been moved to a new system.
I will say that the actual customer migration was a bit of a bear. I thought at first that we would be able to do it by hand in the backend, but I ended up having to write some fairly involved scripts to get the job done. There were just too many identity columns, and it's not like you can just turn off constraints temporarily when you're importing into a live production system.