I've finally managed to narrow this down to a reproducible set of scripts and have created a GH issue: https://github.com/apache/couchdb/issues/1063
The summary is that I believe there is a resource leak in CouchDB when you abort continuous listening on the _global_changes database. Fortunately, there appears to be a workaround (if your use case supports it) where you can use feed=longpoll instead of feed=continuous I hope this saves someone else some headache! On Tue, Dec 5, 2017 at 2:48 PM Geoffrey Cox <redge...@gmail.com> wrote: > Hi Adam, quick follow-up: is it possible that writes can also be designed > to a "primary" node, like the `stale` option for a view? I was originally > thinking that the issue is with reading data via a view, but now I'm > thinking it may be related to writing data and those writes somehow > triggering these persistent and heavyweight couchjs processes. It's tough > to say as I'd imagine that you don't have couchjs load unless you have > frequent writing and reading. I'm still trying to isolate the issue and it > is difficult as the problem only seems to happen in a production env and > only with *all* the production code, figures ;) > > On Tue, Dec 5, 2017 at 12:13 PM Geoffrey Cox <redge...@gmail.com> wrote: > >> Hey Adam, >> >> Attached is my local.ini and the design doc with the view JS. >> >> Please see my responses below: >> >> Thanks for the help! >> >> On Tue, Dec 5, 2017 at 8:55 AM Adam Kocoloski <kocol...@apache.org> >> wrote: >> >>> Hi Geoff, a couple of additional questions: >>> >>> 1) Are you making these view requests with stale=ok or >>> stale=update_after? >>> >> GC: I am not using the stale parameter >> >>> 2) What are you using for N and Q in the [cluster] configuration >>> settings? >>> >> GC: As per the attached local.ini, I specified n=2 and am using the >> default q=8. >> >>> 3) Did you take advantage of the (barely-documented) “zones" attribute >>> when defining cluster members? >>> >> GC: As per the attached local.ini, I have *not* specified this option. >> >>> 4) Do you have any other JS code besides the view definitions? >>> >> GC: When you refer to JS code, I think you mean in terms of JS code "in" >> CouchDB and if that is the case then my only JS code is very simple views >> like those in the attached view.json. (I know that I really need to break >> out the views so that there is one view per doc, but I haven't quite gotten >> around to refactoring this and I don't believe this is causing the CPU >> usage) >> >>> >>> Regarding #1, the cluster will actually select shards differently >>> depending on the use of those query parameters. When your request >>> stipulates that you’re OK with stale results the cluster *will* select a >>> “primary” copy in order to improve the consistency of repeated requests to >>> the same view. The algorithm for choosing those primary copies is somewhat >>> subtle hence my question #3. >>> >>> If you’re not using stale requests I have a much harder time explaining >>> why the 100% CPU issue would migrate from node to node like that. >>> >>> Adam >>> >>> > On Dec 5, 2017, at 9:36 AM, Geoffrey Cox <redge...@gmail.com> wrote: >>> > >>> > Thanks for the responses, any other thoughts? >>> > >>> > FYI: I’m trying to work on a very focused test case that I can share >>> with >>> > the Dev team, but it is taking a little while to narrow down the exact >>> > cause. >>> > On Tue, Dec 5, 2017 at 4:43 AM Robert Samuel Newson < >>> rnew...@apache.org> >>> > wrote: >>> > >>> >> Sorry to contradict you, but Cloudant deploys clusters across amazon >>> AZ's >>> >> as standard. It's fast enough. It's cross-region that you need to >>> avoid. >>> >> >>> >> B. >>> >> >>> >>> On 5 Dec 2017, at 09:11, Jan Lehnardt <j...@apache.org> wrote: >>> >>> >>> >>> Heya Geoff, >>> >>> >>> >>> a CouchDB cluster is designed to run in the same data center / with >>> >> local are networking latencies. A cluster across AWS Availability >>> Zones >>> >> won’t work as you see. If you want CouchDB’s in both AZs, use regular >>> >> replication and keep the clusters local to the AZ. >>> >>> >>> >>> Best >>> >>> Jan >>> >>> -- >>> >>> >>> >>>> On 4. Dec 2017, at 19:46, Geoffrey Cox <redge...@gmail.com> wrote: >>> >>>> >>> >>>> Hi, >>> >>>> >>> >>>> I've spent days using trial and error to try and figure out why I am >>> >>>> getting a very high CPU load on only a single node in my cluster. >>> I'm >>> >>>> hoping someone has an idea of what is going on as I'm getting stuck. >>> >>>> >>> >>>> Here's my configuration: >>> >>>> >>> >>>> 1. 2 node cluster: >>> >>>> 1. Each node is located in a different AWS availability zone >>> >>>> 2. Each node is a t2 medium instance (2 CPU cores, 4 GB Mem) >>> >>>> 2. A haproxy server is load balancing traffic to the nodes using >>> round >>> >>>> robin >>> >>>> >>> >>>> The problem: >>> >>>> >>> >>>> 1. After users make changes via PouchDB, a backend runs a number of >>> >>>> routines that use views to calculate notifications. The issue is >>> that >>> >> on a >>> >>>> single node, the couchjs processes stack up and then start to >>> consume >>> >>>> nearly all the available CPU. This server then becomes the >>> "workhorse" >>> >> that >>> >>>> always does *all* the heavy duty couchjs processing until I restart >>> >> this >>> >>>> node. >>> >>>> 2. It is important to note that both nodes have couchjs processes, >>> but >>> >>>> it is only a single node that has the couchjs processes that are >>> using >>> >> 100% >>> >>>> CPU >>> >>>> 3. I've even resorted to setting `os_process_limit = 10` and this >>> just >>> >>>> results in each couchjs process taking over 10% each! In other >>> words, >>> >> the >>> >>>> couchjs processes just eat up all the CPU no matter how many couchjs >>> >>>> process there are! >>> >>>> 4. The CPU usage will eventually clear after all the processing is >>> >> done, >>> >>>> but then as soon as there is more to process the workhorse node will >>> >> get >>> >>>> bogged down again. >>> >>>> 5. If I restart the workhorse node, the other node then becomes the >>> >>>> workhorse node. This is the only way to get the couchjs processes to >>> >> "move" >>> >>>> to another node. >>> >>>> 6. The problem is that this design is not scalable as only one node >>> can >>> >>>> be the workhorse node at any given time. Moreover this causes >>> specific >>> >>>> instances to run out of CPU credits. Shouldn't the couchjs >>> processes be >>> >>>> spread out over all my nodes? From what I can tell, if I add more >>> >> nodes I'm >>> >>>> still going to have the issue where only one of the nodes is getting >>> >> bogged >>> >>>> down. Is it possible that the problem is that I have 2 nodes and >>> >> really I >>> >>>> need at least 3 nodes? (I know a 2-node cluster is not very typical) >>> >>>> >>> >>>> >>> >>>> Things I've checked: >>> >>>> >>> >>>> 1. Ensured that the load balancing is working, i.e. haproxy is >>> indeed >>> >>>> distributing traffic accordingly >>> >>>> 2. I've tried setting `os_process_limit = 10` and >>> >> `os_process_soft_limit >>> >>>> = 5` to see if I could force a more conservative usage of couchjs >>> >>>> processes, but instead the couchjs processes just consume all the >>> CPU >>> >> load. >>> >>>> 3. I've tried simulating the issue locally with VMs and I cannot >>> >>>> duplicate any such load. My guess is that this is because the nodes >>> are >>> >>>> located on the same box so hop distance between nodes is very small >>> and >>> >>>> this somehow keeps the CPU usage to a minimum >>> >>>> 4. I've tried isolating the issue by creating short code snippets >>> that >>> >>>> intentionally try to spawn a lot of couchjs processes and they are >>> >> spawned >>> >>>> but don't consume 100% CPU >>> >>>> 5. I've tried rolling back from CouchDB 2.1.1 to CouchDB 2.0 and >>> this >>> >>>> doesn't seem to change anything >>> >>>> 6. The only error entries in my CouchDB logs are like the following >>> and >>> >>>> I don't believe they are related to my issue: >>> >>>> 1. >>> >>>> >>> >>>> [error] 2017-12-04T18:13:38.728970Z couchdb@172.31.83.32 >>> >> <0.13974.79> >>> >>>> 4b0b21c664 rexi_server: from: couchdb@172.31.83.32(<0.20638.79>) >>> >> mfa: >>> >>>> fabric_rpc:open_shard/2 throw:{forbidden,<<"You are not allowed >>> to >>> >> access >>> >>>> this db.">>} >>> >>>> >>> >> >>> [{couch_db,open,2,[{file,"src/couch_db.erl"},{line,185}]},{fabric_rpc,open_shard,2,[{file,"src/fabric_rpc.erl"},{line,267}]},{rexi_server,init_p,3,[{file,"src/rexi_server.erl"},{line,139}]}] >>> >>>> >>> >>>> Does CouchDB have some logic built in that spawns a number of >>> couchjs >>> >>>> processes on a "primary" node? Will future view processing then >>> always >>> >> be >>> >>>> routed to this "primary" node? >>> >>>> >>> >>>> Is there a way to better distribute these heavy duty couchjs >>> processes? >>> >> Is >>> >>>> it possible to limit their CPU consumption? (I'm hesitant to start >>> down >>> >> the >>> >>>> path of using something like cpulimit as I think there is a root >>> problem >>> >>>> that needs to be addressed) >>> >>>> >>> >>>> I'm running out of ideas and hope that someone has some notion of >>> what >>> >> is >>> >>>> causing this bizarre load or if there is a bug in CouchDB. >>> >>>> >>> >>>> Thank you for any help you can provide! >>> >>>> >>> >>>> Geoff >>> >>> >>> >>> -- >>> >>> Professional Support for Apache CouchDB: >>> >>> https://neighbourhood.ie/couchdb-support/ >>> >>> >>> >> >>> >> >>> >>>