Showing posts with label elasticsearch. Show all posts
Showing posts with label elasticsearch. Show all posts

The No-BS guide to AutoComplete and FuzzySearch in Elasticsearch


Before we begin.. Here are a few basics.

Analyzer:

An analyzer does the analysis or splits the indexed phrase/word into tokens/terms upon which the search is performed with much ease.

An analyzer is made up of tokenizers and filters.

There are numerous analyzers in elasticsearch, by default;
here, we use some of the custom analyzers tweaked to meet our requirements.

Filter:

A filter removes/filters keywords from the query. Useful when we need to remove false positives from the search results based on the inputs.

We will be using a stop word filter to remove the specified keywords in the search configuration from the query text.

Tokenizer:

The input string needs to be split, to be searched against the indexed documents. We are about to use ngram here, which splits the query text into sizeable terms.

Mappings:

The created analyzer needs to be mapped to a field name, for it to be efficiently used while querying.

T'is time!!!

Now that we have covered the basics, it's time to create our index.

Fuzzy Search:

The first upon our index list is fuzzy search:

Index Creation:

curl -vX PUT http://localhost:9200/books -d @fuzzy_index.json \
--header "Content-Type: application/json"
 

And, the following books and their corresponding authors are loaded to the index.

name author
To Kill a Mockingbird Harper Lee
When You're Ready J.L. Berg
The Book Thief Markus Zusak
The Underground Railroad          Colson Whitehead
Pride and Prejudice Jane Austen
Ready Player One Ernest Cline

When a fuzzy query such as:

This query with the match keyword as "ready" returns the matched books ready as a keyword in the phrase; as,

AutoComplete:

Next up, is the autocomplete. The only difference between a fuzzy search and an autocomplete is the min_gram and max_gram values.

In this case, depending on the number of characters to be auto-filled, the min_gram and max_gram values are set, as follows:


Elasticsearch to MongoDB Migration - MongoES

The following are some of the instances where the developers simply love to hate!
  • The one-last-thing syndrome - This reminds me of the following quote:
  The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.
Tom Cargill, Bell Labs, from the book `Programming Pearls `
  • QAs declaring certain undocumented features to be as bugs - Seriously, this create traumas for a devloper.
  • Interruptions during coding - Here's an idea. Try talking to developers while they code; chances are, they have just about <10% of your attention. 
There are some problems which we get used to..

But, there are others which makes us wanna do this..



  • DISCONNECTION FROM THE SERVER DUE TO BAD INTERNET DURING A MIGRATION - Ouch!! That's gotta hurt real bad.

Talking about ES to MongoDB Migration 

- How hard could that be?

Good Side:
JSON objects are common for both.
Numerous tools to choose from, for migration.
Bad Side: 
The Migration can be hideous, and can eat up a lot of the system resources. Be ready for a system-freeze, in case the migration tool uses a queue.
Ugly Side:
Can never be resumed from the point of failure. If the connectivity goes down during the migration; the transferred collection has to be deleted and the data transfer has to be initiated once again from the beginning.


Alright, there's nothing there to be felt bad about.

Enter, MongoES.



MongoES is a pure python3-bred Migration tool to migrate documents from the elasticsearch's index to the MongoDB collections.

It's robust in it's native way; no queues/message brokers are involved; which means that there won't be any memory spikes or system freezes.

This became achievable due to the fact that MongoES specifically uses a tagging strategy prior to the migration. The tagging happens in the source elasticsearch, which stands as a checkpoint during the migration.

Why a new custom id tagging, while there's an _id already?

Unless the documents are explicitly tagged, the _id fields in elasticsearch documents are a bunch of alphanumeric strings generated to serialize the documents. These _id columns become unusable, since queries/aggregations can not be run using them.

MongoES - How to:
  1. Install all the Prerequisites.
  2. Clone the repository from https://github.com/datawrangl3r/mongoes.git
  3. Edit the mongoes.json file according to your requirements.

  4. Make sure that both the elasticsearch and mongoDB services are up and running, and fire up the migration by keying in:

  5. Sit back and relax; for we got you covered! The migration's default value is 1000 documents per transfer.
Happy Wrangling!!! :)

ES Index - S3 Snapshot & Restoration:

The question is. What brings you here? Fed up with all the searches on how to back-up and restore specific indices? 

Fear not, for your search quest ends here.!

After going through dozens of tiny gists and manual pages, here it is. We've done all the heavy lifting for you.



The following tutorial was tested on elasticsearch V5.4.0

And before we proceed, remember:

Do's:

Make sure that the elasticsearch version of the backed-up cluster/node <= Restoring Cluster's version.

Dont's:

Unless it's highly necessary;

        curl -X DELETE 'http://localhost:9200/nameOfTheIndex

              - deletes a specific index

Especially not, when you are drunk!:

        curl -X DELETE 'http://localhost:9200/_all

              - deletes all indexes (This is where the drunk part comes in..!!)



Step1: Install S3 plugin Support:

        sudo bin/elasticsearch-plugin install repository-s3
                                  (or)
        sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install repository-s3

Depends on where your elasticsearch-plugin executable is installed. This enables the elasticsearch instance to communicate with the AWS S3 buckets.

Step2: Input the Snapshot registration settings:

METHOD: PUT

URL: http://localhost:9200/_snapshot/logs_backup?verify=false&pretty

PAYLOAD:
                {
                  "type": "s3",
                  "settings": {
                    "bucket": "WWWWWW",
                    "region": "us-east-1",
                    "access_key": "XXXXXX",
                    "secret_key": "YYYYYY"
                  }
                }


In the URL:
       - logs_backup: Name of the snapshot file

In the payload JSON:
        - bucket: "WWWWW" is where you enter the name of the bucket.
        - access_key & secret_key: The values "XXXXXX" and "YYYYYY" is where we key in the access key and secret key for the buckets based on the IAM policies - If you need any help to find it, here's a link which should guide you through (https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/).
        - region: the region where the bucket is hosted (choose any from http://docs.aws.amazon.com/general/latest/gr/rande.html).

This should give a response as '{"acknowledged": "true"}'.

Step3: Cloud-Sync - list all Snapshots:

METHOD: GET 

URL: http://localhost:9200/_cat/snapshots/logs_backup?v


In the URL:
       - logs_backup: Name of the snapshot file
Time to sync up all the list of snapshots. If all our settings have been synced up just fine; we should end up with a list of indices, close to that of what is shown below:



  

Step4: Creating a Snapshot:

METHOD: PUT

URL: http://localhost:9200/_snapshot/logs_backup/type_of_the_backup?wait_for_completion=true

PAYLOAD:
            {
                "indices": "logstash-2017.11.21",
                "include_global_state": false,
                "compress": true,
                "encrypt": true
            }


In the URL:
       - logs_backup : Name of the snapshot file
       - type_of_the_backup : Could be any string
     
In the payload JSON:
        - indices: Correspond to the index which is to be backed-up to S3 bucket. In the case of multiple indices to back up under a single restoration point, the indices can be entered in the form of an array.
        - include_global_state: set to 'false' just to make sure there's cross-version compatibility. WARNING: If set to 'true', the index can be restored only to the ES of the source version.
        - compress: enables compression of the index meta files backed up to S3.
        - encrypt: In case if extra encryption on the indices is necessary.

This should give a response as '{"acknowledged": "true"}'

Step5: Restoring a Snapshot:

METHOD: PUT

URL: http://localhost:9200/_snapshot/name_of_the_backup/index_to_be_restored/_restore

PAYLOAD:
            {
                "ignore_unavailable": true,
                "include_global_state": false
            }

In the URL:
       - logs_backup: Name of the snapshot file
       - index_to_be_restored: Any of the index from the id listed in Step:3

In the payload JSON:
        - ignore_unavailable: It's safe to set this to true, to avoid unwanted checks.
        - include_global_state: set to 'false' just to make sure there's cross-version compatibility. WARNING: If set to 'true', the index can be restored only to the ES of the source version.

This should give a response as '{"acknowledged": "true"}'

Et Voila!  The restoration is complete.

And Don't forget to recycle the space corresponding to the index by safely deleting it - Reuse, Reduce & Recycle :)

Happy Wrangling!!!

ELK Stack... Not!!! FEK, it is.!!! Fluentd, Elasticsearch & Kibana

If you are here, you probably know what elasticsearch is and at some point, trying to get into the mix. You were searching for the keywords "logging and elasticsearch" or perhaps, "ELK"; and probably ended up here. Well, you might have to take the following section with a pinch of salt, especially the "ELK Stack"  fam.

At least from my experience, working for start-ups teaches oneself, a lot of lessons and one of the vast challenges include minimizing the resource utilization bottlenecks.
On one hand, the logging and real-time application tracking are mandatory; while on the other hand, there's a bottleneck in the allocated system resource, which is probably an EC2 instance with 4Gigs of RAM.

ELK Stack 101:

Diving in, ELK => Elasticsearch, Logstash, and Kibana. Hmm, That doesn't add up; don't you think? Elasticsearch stores the reformed log inputs, Logstash chops up the textual logs and transforms them to facilitate query, derivation of meaningful context, thereby, aiding as an input source to be visualized in Kibana.
Logstash uses grok patterns to chop up the log, doesn't it? So, an essential amount of time needs to be invested in learning how these patterns are different from that of traditional regular expressions.
But... But, who's gonna ship the logs from the application to Logstash and this shipping needs to be seem-less. Well, There's filebeat provided by elastic co, to ship all those.

So, Is it supposed to be ELFK or perhaps, FLEK stack? (WT*) 
You, be the judge!

Using four applications, singing to each other, what could go wrong?

WARNING: The following infographic may contain horrifying CPU spikes, that some readers might find disturbing.


Well.. Well.. Well.. What do we have here?

Extracting valuable information from logs is more like an excavation, digging deep to excavate the hidden treasures. It can't be at the cost of resource utilization.

Introducing, the FEK Stack.

Enter Fluentd AKA td-agent, an open-source data collection tool written in Ruby (not JAVA!!! Ruby - 1 Java - 0).


The setup is way too easy, that you can be up and running in no time.


Locate to /etc/td-agent/ and replace the existing configuration template (td-agent.conf) with the following configuration.


The parameters are self-explanatory and the keyword: format is where the regex for log chopping is given. An important thing to note is the tag keyword. The value described here should be used in the <match> segment. This bonding between the source and the mapping happens with the aid of this keyword.

For demonstration purposes, you can use the following snippet of code for random log file generation.

https://github.com/datawrangl3r/logGenerator

The configuration file is synced with this code; it shouldn't be a hassle.

Thanks for reading.
Let me know how it all worked out in the comments below!

Featured Posts

ETL & Enterprise Level Practices

  ETL Strategies & Pipelines have now become inevitable for cloud business needs. There are several ETL tools in the market ranging fro...