Couchbase Eventing: Small Scripts hat Solve Big Problems at Scale – DZone Cloud | xxxCouchbase Eventing: Small Scripts hat Solve Big Problems at Scale – DZone Cloud – xxx
菜单

Couchbase Eventing: Small Scripts hat Solve Big Problems at Scale – DZone Cloud

四月 30, 2020 - MorningStar

Over a million developers have joined DZone.

  • Couchbase Eventing: Small Scripts hat Solve Big Problems at Scale - DZone Cloud

    {{node.title}}

    {{node.type}} · {{ node.urlSource.name }} by

    Download {{node.downloads}}

  • {{totalResults}} search results

{{announcement.body}}

{{announcement.title}}

Let’s be friends:

= 1024)” dc-slot=”ads.sl1.slot(articles[0], 0)” tags=”ads.sl1.tags(articles[0], 0)” size=”ads.sl1.size(articles[0], 0)” style=”border:0;”>
1 && !articles[0].partner.isSponsoringArticle && (width >= 1024)” dc-slot=”ads.sb2.slot(articles[0], 0)” tags=”ads.sb2.tags(articles[0], 0)” size=”ads.sb2.size(articles[0], 0)” is-nobid=”true”>

Couchbase Eventing: Small Scripts hat Solve Big Problems at Scale

DZone ‘s Guide to

Couchbase Eventing: Small Scripts hat Solve Big Problems at Scale

With simple functions come great power. Couchbase Eventing is must have tool in your big data arsenal allowing small scripts to overcome hard to solve problems.

Jun. 07, 20 · Cloud Zone ·

Free Resource

Join the DZone community and get the full member experience.

Join For Free

Eventing: Simple Yet Powerful

Eventing allows small scripts to overcome hard to solve problems. First off, let’s look at the basic Eventing LifecycleCouchbase Eventing: Small Scripts hat Solve Big Problems at Scale - DZone Cloud The steps below show how easy it is to write and use an Eventing Function:

  • Add (or import) an Eventing Function via Couchbase Server’s UI.
  • Assign a data source, a scratchpad bucket, and some bindings to manipulate documents or communicate with the outside world.
  • Implement some JavaScript code to process the received mutation.
  • Save your new Function and hit "Deploy"

That’s it; you now have a distributed function responding to mutations in your data set in real-time across your entire cluster. The Eventing service provides an infrastructure-less platform that can scale your Eventing Functions as your business experiences growth whether a one-time spike or a monthly increase in data stores or clients served without concern for the fact that your JavaScript-based Eventing functions are running in a robust reliable parallel distributed fashion.  To learn more about Couchbase Eventing please refer to the Eventing Overview in our documentation. The examples in this article below show that in some cases Eventing can act like a drop of oil to needed "free up" the moving parts of your applications.

Couchbase a Database You Build to Order

I like to think of a Couchbase cluster as a set of scalable interoperable "microservices". These services can be wired together and sized to meet a specific set of operational and business needs. Couchbase Eventing: Small Scripts hat Solve Big Problems at Scale - DZone Cloud Couchbase provides Multi-dimensional Scaling, or MDS, across five key services with minimal resource interference between them. Furthermore, each Couchbase service is independently scalable, via simply adding more nodes. This allows customers to create the ideal multi-node cluster at the possible lowest TCO for the task(s) at hand.

  • The Data nodes easily scale to provide JSON aware KV operations at-scale for single and multi-record lookups is extremely fast. Did I did mention that for single and multi-record lookups it is extremely fast?
  • The Query nodes easily scale to provide indexes and also N1QL, a SQL enhancement that works with natively with JSON documents, that allows programmers get up and running quickly without having to learn a new way of thinking.
  • The Search nodes easily scale to provide full-text search for natural-language querying featuring: language-aware searching, scoring of results, and fast FTS based indexes,
  • The Analytics node easily scales to parallel data management capability to efficiently run complex queries: large ad hoc join, set, aggregation, and grouping operations across large datasets.
  • The Eventing service easily scale to provide a computing paradigm that developers can use to handle data changes (or mutations) and react to them in real-time.

Like all product lines the newer services in Couchbase Query, Search, and Eventing, and Analytics have a few warts but taken as a whole the complete basket provides a unified suite, or a one-stop shop to solve a myriad of problems. I mean seriously if you don’t care about a unified product and all you are going to do is use FTS you might just consider using Elasticsearch but once you need to integrate your FTS results with N1QL (SQL for JSON) you might have been much better off just starting with Couchbase. Today we are going to utilize just two services: 1) the primary KV service provided by Data nodes 2) the Eventing Service. I will highlight through a few tiny JavaScript functions how you can overcome some hard at-scale problems by leveraging the Eventing Service.

Prerequisites

In this article we will be using the latest GA version, Couchbase version 6.5.1 However, if you are not familiar with Couchbase or the Eventing service please walk through GET STARTED and one Eventing example specifically refer to the following:

  • Setup a working Couchbase 6.5.1 server as per the directions in Start Here!
  • Understand how to deploy a basic Eventing function as per the directions in the Data Enrichment example specifically "Case 2" where we will only use one bucket the ‘source’ bucket.

Enriching Data via Eventing

A Typical Customer Problem

A live production system has stored billions of documents. A new business need has occurred where the existing data needs to be enriched.  This requirement of additional data impacts the complete document set.  The operational impact encompasses both old or historic data and also new or mutating data. The business needs to keep the production system running non-stop and continuously respond to new real-time data. Consider a somewhat contrived example application a GeoIP lookup service. This utility needs a dataset to enable looking up countries by IPV4 address ranges. The initial implementation stored records as follows:

JSON

 

x
 

1

{

2

  "type": "ip_country_map",

3

  "country": "RU",

4

  "ip_start": "7.12.60.1",

5

  "ip_end": "7.62.60.9"

6

}

Months later new business requirements change. The engineering needed the JSON documents to be enriched with new fields.  The requirement was to include the numeric representations of the two existing IPV4 address.

JSON

 

xxxxxxxxxx
1

 

1

{

2

  "type": "ip_country_map",

3

  "country": "RU",

4

  "type": "ip_country_map",

0

5

  "type": "ip_country_map",

1

6

  "type": "ip_country_map",

2

7

  "type": "ip_country_map",

3

8

  "type": "ip_country_map",

4

Eventing to The Rescue

A simple nineteen (13) line JavaScript (2 of which comments) Eventing Function can be written and deployed to solve the issue with minimal resources.

JavaScript

 

  "type": "ip_country_map",

5

1

13

 

1

  "type": "ip_country_map",

6

2

  "type": "ip_country_map",

7

3

  "type": "ip_country_map",

8

4

  "type": "ip_country_map",

9

5

  "country": "RU",

0

6

  "country": "RU",

1

7

  "country": "RU",

2

8

  "country": "RU",

3

9

  "country": "RU",

4

10

  "country": "RU",

5

11

  "country": "RU",

6

12

  "country": "RU",

7

13

  "country": "RU",

8

By deploying the above Function with a "Feed boundary" set to "Everything" all documents of type: "ip_country_map" are processed and enriched. The Eventing Function is left "deployed" reacting to all new inserts or updates (or mutations) in real-time enriching new items and also updating existing items on changes to "ip_start_num" or "ip_end_num" to the proper "numeric" representations. Because the documents are enriched (the old fields are still present) the existing production applications will still work.  All new or changed data is updated in real-time to the new schema.  The GeoIP application components are decoupled via this simple Eventing Function such that they can be upgraded one at a time. When all production components have been updated the Eventing Function can be undeployed and decommissioned.

Purging Stale Data via Eventing

A Typical Customer Problem

A live production system has stored over 7 billion documents. All documents have an automatic expiration (or TTL for time to live) set. The production environment constantly receives new data and constantly expires old data. An operational mistake was made resulting in 2 billion documents being created without an expiration. The customer didn’t have the resources (nor desired to pay for the resources) to create a large index to utilize N1QL to identify select and purge the data that lacked an active (non-zero TTL) when it was no longer useful.

Eventing to The Rescue

A simple six (6) line JavaScript (2 of which are comments) Eventing Function was deployed and solve the issue with minimal resources.

JavaScript

 

  "country": "RU",

9

1

 

1

  "ip_start": "7.12.60.1",

0

2

  "ip_start": "7.12.60.1",

1

3

  "ip_start": "7.12.60.1",

2

4

  "ip_start": "7.12.60.1",

3

5

  "ip_start": "7.12.60.1",

4

6

  "ip_start": "7.12.60.1",

5

7

  "ip_start": "7.12.60.1",

6

By deploying the above Function with a "Feed boundary" set to "Everything" the entire document set in the source bucket was scanned. All documents with a non-zero TTL (meaning they had no expiration) were ignored.  Only the matching documents with a TTL greater than zero are deleted. Once the source bucket was cleaned the Eventing Function was undeployed as it was used as an administrative tool. Note we could replace the expiration !== 0 test in our JavaScript to filter out data for any needed purpose. Pretty easy to guess what we are doing below:

JavaScript

 

  "ip_start": "7.12.60.1",

7

1

 

1

  "ip_start": "7.12.60.1",

8

2

  "ip_start": "7.12.60.1",

9

3

  "ip_end": "7.62.60.9"

0

4

  "ip_end": "7.62.60.9"

1

5

  "ip_end": "7.62.60.9"

2

6

  "ip_end": "7.62.60.9"

3

In fact, we could easily update the above to perform a cascade archive and delete not only of the customer but of any other related information such as orders, returns and shipping addresses. Refer to the example Cascade Delete in the Eventing Documentation.

Stripping Sensitive Data via Eventing

A Typical Customer Problem

A company running Couchbase on-premises in production was needed to share customer profile information (150M and growing). Their business partner is also running Couchbase but in a cloud provider, AWS. Given a typical profile record like the following:

JavaScript

 

  "ip_end": "7.62.60.9"

4

1

48

 

1

  "ip_end": "7.62.60.9"

5

2

  "ip_end": "7.62.60.9"

6

3

  "ip_end": "7.62.60.9"

7

4

  "ip_end": "7.62.60.9"

8

5

  "ip_end": "7.62.60.9"

9

6

}

0

7

}

1

8

}

2

9

}

3

10

}

4

11

}

5

12

}

6

13

}

7

14

}

8

15

}

9

16

xxxxxxxxxx

0

17

xxxxxxxxxx

1

18

xxxxxxxxxx

2

19

xxxxxxxxxx

3

20

xxxxxxxxxx

4

21

xxxxxxxxxx

5

22

xxxxxxxxxx

6

23

xxxxxxxxxx

7

24

xxxxxxxxxx

8

25

xxxxxxxxxx

9

26

{

0

27

{

1

28

{

2

29

{

3

30

{

4

31

{

5

32

{

6

33

{

7

34

{

8

35

{

9

36

  "type": "ip_country_map",

0

37

  "type": "ip_country_map",

1

38

  "type": "ip_country_map",

2

39

  "type": "ip_country_map",

3

40

  "type": "ip_country_map",

4

41

  "type": "ip_country_map",

5

42

  "type": "ip_country_map",

6

43

  "type": "ip_country_map",

7

44

  "type": "ip_country_map",

8

45

  "type": "ip_country_map",

9

46

  "country": "RU",

0

47

  "country": "RU",

1

48

  "country": "RU",

2

They couldn’t just share the entire profile since it contained sensitive data on user preferences and payment methods.  They only needed to share a limited subset like the following:

JavaScript

 

  "country": "RU",

3

1

20

 

1

  "country": "RU",

4

2

  "country": "RU",

5

3

  "country": "RU",

6

4

  "country": "RU",

7

5

  "country": "RU",

8

6

  "country": "RU",

9

7

  "type": "ip_country_map",

00

8

  "type": "ip_country_map",

01

9

  "type": "ip_country_map",

02

10

  "type": "ip_country_map",

03

11

  "type": "ip_country_map",

04

12

  "type": "ip_country_map",

05

13

  "type": "ip_country_map",

06

14

  "type": "ip_country_map",

07

15

  "type": "ip_country_map",

08

16

  "type": "ip_country_map",

09

17

  "type": "ip_country_map",

10

18

  "type": "ip_country_map",

11

19

  "type": "ip_country_map",

12

20

  "type": "ip_country_map",

13

The customer wanted to replace middle-wear SPARK solution required hours on failure to initialize and only provided slow batch process (hours to reflect updates) and sync up the profile information in real-time.

How Eventing Helps

A simple eight (9) line JavaScript (3 of which are comments) Eventing Function was deployed and solve the issue with minimal resources.

JavaScript

 

  "type": "ip_country_map",

14

1

 

1

  "type": "ip_country_map",

15

2

  "type": "ip_country_map",

16

3

  "type": "ip_country_map",

17

4

  "type": "ip_country_map",

18

5

  "type": "ip_country_map",

19

6

  "type": "ip_country_map",

20

7

  "type": "ip_country_map",

21

8

  "type": "ip_country_map",

22

9

  "type": "ip_country_map",

23

By deploying the above Function with a "Feed boundary" set to "Everything" the entire document set in the source bucket was scanned and all documents of type: "master_profile" were processed and only a sub-document from each profile without the sensitive information was copied to the shared destination bucket. The Eventing Function is always left deployed reacting to all user profile changes (or mutations) in real-time and forwarding each and every mutation to the AWS destination bucket.

Resources

References

Like This Article? Read More From DZone

Topics:
big data ,eventing ,java ,javascript ,scaling ,scrips ,tutorial

Published at DZone with permission of Jon Strabala . See the original article here.

Opinions expressed by DZone contributors are their own.

Cloud Partner Resources

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.linkDescription }}

{{ parent.urlSource.name }}

by

CORE

· {{ parent.articleDate | date:’MMM. dd, yyyy’ }} {{ parent.linkDate | date:’MMM. dd, yyyy’ }}


Notice: Undefined variable: canUpdate in /var/www/html/wordpress/wp-content/plugins/wp-autopost-pro/wp-autopost-function.php on line 51