-
Couldn't load subscription status.
- Fork 1.3k
Description
Hi,
We are getting errors like below while both publishing and receiving events.
SubscriberExecutionFailedException-->23505: duplicate key value violates unique constraint "published_pkey" DETAIL: Key ("Id")=(1613554411973534) already exists."
We run our application in a k8n cluster with 10 or more pods distributed to multiple nodes. (We use openshift 3.11 version if it helps). To my guess it is due to the SnowflakeId implementation. It uses mac addresses last 10 bits to generate a workerId if it is not provided in environmental variable CAP_WORKERID. There is a possibility that those 10 bits may be the same in a multi node cluster. In a single node cluster the OUI part is unique as the initial part is the same but when it comes to multiple nodes there is a possibility that the initial part of the mac is different but the last part is the same. When this happens and under a good load we get this kind of errors both while publising or receiving. It is an option to set CAP_WORKERID for each pod but openshift gives you the only one environmental configuration per deployment config not per pod. (It doesn't make sense having multiple deployment configs for the same service as the number is dynamic due to load etc.)
I have created a ugly workaround like below. I have used redis to increment a number to assign as workerId and set it to CAP_WORKERID env value.
private const string CapWorkerIdKey = "CAP_WORKERID";
private static void ConfigureWorkerId(IServiceCollection services)
{
var sp = services.BuildServiceProvider();
var redis = sp.GetRequiredService<IRedisCacheClient>();
var db = redis.Db3.Database;
var workerId = db.StringIncrement(CapWorkerIdKey, 10);
db.KeyExpire(CapWorkerIdKey, TimeSpan.FromMinutes(5));
Environment.SetEnvironmentVariable(CapWorkerIdKey, workerId.ToString()); // Need to set EnvironmentTarget.Machine in older versions like 6.x
}
It seems to work for me. But a singleton service would be nicer to have for SnowflakeId where I can fiddle the workerId generation or entire SnowflakeId generation process.