I've developed a snippet of code so that it tries to create 100000 Aliases on Elasticsearch. I found that as long as number of Aliases was increasing the time takes for creation an Alias was raising as well. It seems complexity of this operation is O(n) that makes no sense.
Are you creating these aliases one-by-one or adding a batch per operation? Which version of Elasticsearch are you on?
In my snippet of code I did in serialized form (one by one). But I have the same problem in another application that try that in parallel. The elastic version is 2.1.1 with 100 shards. The problem is just for Alias operations (create/delete) and other operations like indexing& searching work well. Do you think it is normal or not?
I suspect each modification to an alias will result in an update to the cluster state, which need to be propagated across the cluster. Elasticsearch 2.x support delta cluster state updates, so it should however have less of an impact compared to earlier versions. As more aliases are added it is possible that more data need to be transferred, resulting in higher latencies. What is the difference in latency between the first and last alias created? Any particular reason you are not creating aliases in bulk?
@Christian_Dahlqvist for the first request it takes around 10 ms and in a linear growth it goes up to 170 ms for 40000th request. I need to create requests on demand, this is why I can't use bulk format. Please note that this is what happens in my simple test case on my PC that provided with 16 gig ram and a fast SSD hard without any Cluster configuration and other loads. In real situation, it event can be worse. I have 2 clustered servers and more than 100000 Alias is made on them. I found for some requests, latency is up to 40s. I really think it is not acceptable.
As was explained in this GitHub issue, the increase in latency as the number of aliases grow is expected.
What is the use case behind creating so many aliases? How often are aliases created in a production setting?
Dear @Christian_Dahlqvist , please let to continue the discussion at https://github.com/elastic/elasticsearch/issues/16853
If you can provide some additional details around your use case and the rationale behind creating this number of aliases, it is possible the community can help suggest alternate approaches to achieving your goals without having to rely so heavily on aliases.
@Christian_Dahlqvist Many thanks for your reply. I described my use-case at https://github.com/elastic/elasticsearch/issues/16853
Please let me follow your reply there.
I think it is better to have the discussion here as it is easier and more accessible to the community compared to GitHub.
If each user in this multi-tenant setup only has access to his/her data, why do you need to create individual aliases at all? Would it be possible to avoid using aliases by e.g. modifying the application logic to ensure that you add a filter and routing parameter depending on the user id to each query and indexing request?
@ebuildy @Clinton_Gormley @Christian_Dahlqvist Yes, it is possible to attach the filter and routing parameter to each request, but it doesn't seem so rational. The filter and routing param are static for each user and it actually doesn't need to be sent for each request. It just makes length of request bigger and logically leads more time to process. I expect Alias as a place for defining such these static info. Elastic can cache these data and even pre-process them to get speed up in terms of performance. However, I don't agree with what @jasontedor said at the GitHub issue . In my opinion, at least for one node cluster, it should be in complexity of O(1) or at most O(logn).
I disagree that adding a filter and/or routing parameter to each request is not rational. I would expect the overhead of doing so for each request to be very, very small, quite possibly not even measurable. I would therefore recommend going down this route, and will leave it with that.
OK, so what is the use cases that alias should be use in? Where is the place that alias can be considered useful?
I linked you to the code.
There are others reasons I didn't get into. For example, index metadata is represented internally by immutable maps that need to be rebuilt every time you add an alias; this is clearly linear in the number of aliases. It doesn't matter if you have one node or not (a point you didn't mention in the original GitHub post), this is still linear and it happens on the master.
@Christian_Dahlqvist, I checked my application logic and found there is an alias usage that seems not be possible to be handled by the approach we discussed. I have some multi-alias queries so that each alias have own routing param. How can I tell elastic to query for 2 different shards with 2 different filters so that I avoid running 2 filters on 2 shards simultaneously?
As @jasontedor said, 100.000 (one hundred thousand) aliases are an anti-pattern.
Aliases are helpful, especially for HTTP clients, to address more than one index, or an index with a complex name, in a painless way. For example, in my ~1000 aliases, I assign a term query to offer a uniform method to filter subsets of docs from a giant index. The setup is performed in bulk, i.e. one big cluster state change.
IMHO I can not understand how 100.000 aliases, which are not set up in bulk but one-by-one, can have a legitimate use case. There are surely other methods to set up a cluster without excessive aliasing for the documents. Last resort is to build a search proxy that adds filter terms automatically to queries.
@jasontedor @jprante few months ago I found an example in elasticsearch documentation which uses alias for each user to route&filter requests. In production, 100000 users is typical and based on the example, I though my usage is OK. But now you say that it is an anti-patter . Elastic's lack of documentation is costing me more than I thought. In my opinion, my usage is not an anti-pattern but also the limitation in implementation of elastic brings this performance penalty.
@mahdi_malaki the documentation does not know about any use case of us at all and must always taken with a grain of salt. I do not agree that 100k users is typical - for example, I have only 50 users, but I would never dare to say that 50 users are typical. I would not generalize from a special use case to others that easily. As with all other software products, every use case must be carefully considered, and set up as a proof of concept before implementing a sustainable model for production. There are even fewer surprises with ES, because the source code is open to the public.
@jprante we actually have 500,000 users and we have plan to grow more than that. Reading that document @mahdi_malaki mentioned in his comment and other weblogs led us to use an Alias per user.
We still Elaborate our solutions...
Now I understand that according to your codes,it is not good practice to add many aliases, but it is the limitation that you have in Elasticsearch and using an Alias per user(that defines routing and Filters per user) looks pretty normal use-case and adding an Alias should not be in complexity of O(n).
Now let's look at the other solution you suggested to use filters and routing per request:
In our application, In addition to user area for search we also have group concept that we previously used the following URL to search groups data in addition to user data(user1,group1, group2 are Aliases): localhost:9200/user1,group1,group2/_search
Sending filters and routings per request is not exactly equal to using multiple Aliases for searching.
Do you have another alternative that works exactly like multi-Aliases search?
Why not skip routing completely? If you are looking to minimise the number of shards hit for a specific query, why not create a reasonable number of single shard indices and allocate users and groups to specific indices at the application level? For each query you can identify the specific indices that hold the users and groups you want to query and just query these. As each index still holds data for a large number of users, it should be possible to keep the shards at a reasonable size and the number of indices down.