-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Guidance on stateless configuration #4107
Comments
Orchard Core will work well on AWS, I've had it running on EC2 instances for a POC. However Distributed services for Orchard Core is still a work in progress by @jtkech . See #2247 for some details on the wip, and what issues multiple instances have (namely caching redistribution, often for the admin)
|
Great, thank you @deanmarcussen. I'll work in those directions. I hoped to avoid a shared volume for tenants.json and other data in App_Data since it would require separate backup and restore operations for recovery scenarios. Does anyone know if there are plans to allow tenants.json to be stored outside App_Data? If not, I can definitely do work in this area, so any thoughts about how best to approach this would be appreciated. |
My only concern is with |
The extension points are As i remember i did an experimental work to keep instances in sync with distributed signals / messages that was also holding some tenant transition states. That's ok to keep running instances in sync but anyway we will still need a distributed / shared store for these tenant configs / settings. So, i think we will need custom implementations of the above services using custom config providers. I can plan to do some versions based on Redis in the distributed branch (as i did for data protection), then @deanmarcussen will be able to do some based on blob ;) But there are many other places where tenants will need to be kept in sync, so for me the natural steps are to rework on the distributed services, maybe multiple PRs, the caching branch being one of them to be 1st merged (after reviewing the caching rules and how some race conditions are managed), then the custom implementations of the above services would be part of this incremental work. But maybe better to wait if we can migrate to 3.0 soon because i have new conflicts every day ;) |
I think we'll need an implementation that will make use of a distributed event broker (SQL Server or Redis). How ready is your branch? We haven't looked at it in a year I assume ;) |
Yes, by using a message bus and we opted to do a 1st concrete implementation based on Redis. Last commit of this branch is on 7 dec 2018. I remember the general concepts but i forgot all the details ;) Update: i think OCC will be ready in 2025 ;) |
I assume we need to store the properties in the database (same json structure/document with yessql) and then send a notification on other nodes to load the tenant. Let's get a quick look at it together if you want. And I am sure @deanmarcussen would love to see that too. |
Yes, this is okay for the shared store and for the notification this is already implemented in the distributed branch through a message bus (but based on redis). |
Ah okay when you want but after all this time not sure i'm ready for the details. |
We have to fight Alzheimer before it's too late |
😄 |
Thanks for considering picking this up. And, thanks for the pointers to the existing interfaces @jtkech. |
So Distributed before OCC @jtkech :) Some thoughts
Definite support from me on this :) |
Thanks again for your help with this. Azure App Configuration sounds like it serves a similar purpose to AWS Parameter Store. I frequently use Parameter Store to centralize storage and management of shared settings and secrets across stateless and serverless architectures. Last night, I successfully wired up Parameter Store for both data protection keys and app settings (via IConfiguration) with OrchardCore. I mention all of that because it may be that providers for both Azure App Configuration and AWS Parameter Store could be implemented behind a common settings interface that enable storing I definitely agree about Redis being a reasonable fit. But, just in terms of striving for a more serverless approach and to avoid higher fixed costs associated with hosting Redis, maybe the interfaces for sync'ing could be abstract enough to allow a lower cost option. For example, simple webhooks could potentially be used together with low cost, high scale pub/sub services like Azure Service Bus and AWS SNS to notify interested parties that tenants.json (and other settings) have changed. Apologies if I'm missing some important requirements here. Just wanted to share thoughts from an interested party. :) |
@mattcrossmarc a common store for tenants.json can be anything, but when we mention redis here is to be able to get all nodes to be aware that the config has changed. Unless there is a way to push notifications when settings have changed? |
Thanks @sebastienros. That's good to hear. Regarding pushing notifications, I would really like to be able to use an AWS SNS topic to which all web app instances subscribe. This could be implemented as an optional OrchardCore module that somehow gets a local, in-app event notification (maybe just a callback I receive from OrchardCore) when tenants.json changes, or more generally when configuration state changes that all instances need to know about. Inside this custom module, I would also expose an HTTPS endpoint that AWS SNS would call anytime new messages are posted to the topic. That way, all app instances can know to reload tenants.json. Then, all I would need is some way to tell OrchardCore to reload tenants.json from the backend store (whatever that is in each case). Let me know if I am making sense on this or you want more details. |
Just wanted to report back on progress (note the numbering change relative to my original list since I added Data Protection as a numbered item as I should have done before): 1. Data Protection in AWS Parameter Store
Also, I set the module priority as was done in the Azure Data Protection module:
The only issue I had was that the When I create a site using a new theme with this module enabled, keys are correctly stored in AWS Parameter Store. Note that a key is created for the Default site when provisioning the site from scratch, but if that is deleted, it is not recreated when the site is restarted as would typically be the case. 2. Use a server database like SQL Server or PostgresQL instead of sqlite. 3. Use Azure blob storage for storing media. 4. Using the database to store content types
5. App_Data/tenants.json 6. wwwroot/is-cache |
@deanmarcussen thanks in advance
Yes, this was the case at some point but we separate it from other config files for perf reasons by providing the minimum set of settings to run a tenant when requested. We have to remember this if coming from another custom source (maybe still a local cache). But for infos the settings reading part uses the same Will see, maybe an idea around the default tenant that always exists, i tried something like that in the distributed branch. Or a way to specify through Then, for the mutable part. Normally a config / setttings source is not mutable, okay but at some point we want to be able to change it with a kind of editor (e.g notepad for a json file). Can be integrated in OC, that's what we do when editing a given tenant or at the end of its setup. Or can be done by an external and more complex centralized tool, in that case the
Maybe not a so big concern because config sources are intended to be load once on startup.
Yes, maybe we could use the above idea around the default tenant, and in that case the requirement would be that the database settings would need to be pre-configured (e.g appsettings.json). Hmm, @mattcrossmarc no problem, happy that i could help you.
Yes, you don't need the Many base services and default implementations are already defined, maybe we need more extension points at the app level to configure custom settings sources. Then we will be able to think about any other possible custom implementations at the tenant level (provided by modules) or at the app level. Need to be done step by step and based on some minimum fondations. That's what i began in #4001 by defining some caching rules, e.g update a local cache only when re-reading data from the store (shared or not), not when storing. I updated most of the tenant level caches but i think we will need to do the same kind of things for our mutable config / settings sources. @sebastienros, before reworking on any distributed / stateless things, i would prefer to wait for #4001 and other adaptations just after as said above. So that when reworking on the distributed branch we will add new things most of the time without having to update many existing implementations. Nothing urgent for me, so we can wait the 3.0 migration if it is better. But if you want such things before 3.0, because i feel that here we need some chronologic steps, maybe as a 1st step we could merge #4001 (after reviewing), maybe not so much more conflicts that i already have every day in the 3.0 banch. |
Another update on my side: 1. Data Protection in AWS Parameter Store
3. Use AWS S3 for storing media One issue I'm still trying to sort out is that most file operations get called twice by OrchardCore. For example, when using the Assets page in Admin, listing the contents of a directory will result in two calls with the same parameters to the file store. Are you seeing the same thing? Maybe I'm wiring up the IMediaFileStore incorrectly, but I'm using the same approach as is used in the AzureBlob media By the way, if you want me to PR these modules back in to OrchardCore, I'm glad to do that. No worries either way and glad to contribute back if you think others might be interested in using the modules. |
@deanmarcussen is best placed to give you more infos, it has a pending PR where azure media has been refactored (e.g where a blob image can be resized by ISharp) and, i think, that will be merged soon. Also, we will migrate to netcore 3.0 soon. |
Thanks for letting me know about both upcoming changes. |
@mattcrossmarc Sounds like you're getting there with S3. For info the PR changing how azure media works is #4025, which hopefully will go in soon, after core3, so you can take a look there to see the changes to the Regarding file operations and multiple calls. The media app generally makes a call to get a directory listing and another call to get a file listing of the current directory. So maybe that is what you mean by multiple calls? I've not seen it make multiple calls for no need, but generally Azure Blob will make a few head requests, because of the inherit design of the underlying library, (basically verifying file existence before making operations), and while I'm less familiar with the S3 library I do use it from time to time, and I think the design is similar. So for example when you check if a file exists, and then (moments later) try to download it, you will have two head requests, and then a stream will open. If you want to, put your S3 file store somewhere on github, and I can make time to have a look and help you out if you need it. |
Just wanted to +1 the idea of stateless tenant.json :) |
@jtkech Can I offer any help? |
@MatthijsKrempel okay, i will let you know, thanks |
I think we are just missing a way to store tenants in the db (or in blob storage). @MatthijsKrempel suggest in the default tenant database. |
I'm a little blocked on the distributed branch, there are new options that i have to discuss with @sebastienros which is too busy, so meanwhile i will re-think about stateless tenants.
|
@jtkech funny, I am a little blocked as well, so I made a start on something here yesterday at lunchtime. Because the Storing in the database in the default tenant made less sense, because the default tenant may or may not have been setup, and how would you load its configuration, if its shell has not been loaded (not so hard via just So what I did so far, to see if it would work, was make a So now I have This way those files are also available to edit from the private blob container, much as if they were in I did also have a look to see if They are useful for centralized configuration, but they have no mutation, which we need for |
@deanmarcussen yes, you understood everything ;)
Would be good to work on it together and maybe also on my others shells and distributed branches where there will be some other related things on which we will need to be in sync. Need to leave, i will think about it this night, if i don't fall asleep in front of my PC, as i did these last nights ;) |
Yes definitely @jtkech let's get together on skype and figure it out. I will try and push something tonight, just for starters, so you can see where it is at :)
I was thinking less about editing from the admin, and more just editing directly on blob storage, as a json file, as you would do with App_Data already. However maybe we could also expose something in the admin as well.
I figured because it is about load balancing that probably we should do all the sources, because otherwise someone will make a config on one server in the For now (because it was easy to cut and paste) I have left it with the files split across tenants. Maybe not the best for
Yes, it could go either way here. I tinkered with blob because it was easy for me ;)
Yes, so many things, I message you tonight if I am awake too ;) |
#1893 seems like a related ticket that can also be closed |
@mattcrossmarc have you open sourced any of your modules related to AWS services? |
@dalenewman I haven't, but I'm glad to share them. Let me get the relevant code moved into a repo that can be made public. |
@dalenewman My apologies for the delay. Here is a repo with the AWS S3 media module, updated for OrchardCore 1.0.0: |
I'm working on building an OrchardCore based web application that will be hosted in AWS on autoscaling containers where state is not preserved.
I understand the need to store data protection keys centrally and plan to use this provider to store them in AWS SSM:
https://aws.amazon.com/blogs/developer/aws-ssm-asp-net-core-data-protection-provider/
And, from the comment linked below, it sounds like it's possible to get to a stateless configuration for other types of data:
#3381 (comment)
Of the 3 requirements listed in the comment above, I understand how to do 1 & 2, but it's unclear to me how to cause OrchardCore to do 3.
1. Use a server database like SQL Server or PostgresQL instead of sqlite.
I plan to use PostgreSQL in AWS RDS.
2. Use Azure blob storage for storing media.
I plan to use AWS S3 for this by writing a custom media storage module like that done for Azure in
OrchardCore.FileStorage.AzureBlob
.3. Using the database to store content types
How is this enabled/configured? My apologies if this is in the documentation or source and I missed it.
Also, I see a couple of other things currently stored in App_Data and wwwroot that may need to be stored elsewhere. Can you please advise either way?
4. App_Data/tenants.json
Can this be stored in the database or elsewhere?
5. wwwroot/is-cache
I have seen references to this being a cache only that does not need to be shared across instances. Is that correct?
Thanks for your guidance.
Matt
The text was updated successfully, but these errors were encountered: