Disclaimer: I am not an expert but wanted to contribute here as I was evaluating similar questions. Please feel free to poke holes in my responses.
Is KGS a separate server?
I believe Yes. Purpose of having a KGS was to asynchronously making keys available to app servers. Therefore, it would make sense to keep KGS as a separate server.
Caching in relation to keys?
I think we should not use distributed cache for KGS. KGS can use local cache to cache some keys so that they could be quickly allotted to asking application servers. As soon as KGS adds keys to its local cache, it can mark them used in Key-DB.
In addition, KGS gives keys to individual app servers which caches keys again in their local cache so that they can avoid the communication to KGS and directly assign keys.
Which server is used for Cleaning Service?
I think we should not use App server for cleaning service. App server is customer facing and should be responsible to support customer queries. App server will do lazy clean up in case a “to-be” expired record is accessed by user. In general, Cleaning service can be run on KGS server which would delete paster records from db and move keys from used key-db to available key-db.
Again, I am novice and just sharing my views about the question. Feel free to question my findings.