The Raspberry Pi, a small yet powerful device, has become increasingly popular for various computing projects, including running large language models (LLMs) like Llama. This blog post provides a detailed guide on setting up your Raspberry Pi, installing Llama, configuring it, and troubleshooting common issues.
Setting Up Your Raspberry Pi
Brining LLama to your Pi
Llama (Large Language Model Meta AI) is a family of autoregressive large language models (LLMs), released by Meta AI starting in February 2023.
Install Git: Open a terminal and ensure that git is installed:
sudo apt update && sudo apt install git
Install Python modules that will work with the model to create a chatbot:
pip install torch numpy sentencepiece
Ensure that you have g++ and build-essential installed, as these are needed to build C applications:
sudo apt install g++ build-essential
Cloning the Repository - LLama.cpp
The main goal of llama.cpp
is to enable LLM inference with minimal setup and state-of-the-art performance on a wide variety of hardware - locally and in the cloud.
git clone https://github.com/ggerganov/llama.cpp
Build the project
cd llama.cpp
make
Wait for the build to complete while you can get a model downloaded
Since Raspberry Pi is a small device, it's wise to get a tiny model and hence we will go with Tiny LLM.
Download any one of the version from here
I used tinyllama-1.1b-chat-v1.0.Q6_K.gguf
Go to /models folder inside llama.cpp and run below command in terminal to download the model
wget https://huggingface.co/TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF/resolve/main/tinyllama-1.1b-chat-v1.0.Q6_K.gguf
Running your model
Hopefully, the make command would have your app setup. Now all you need to do is run the server -
./server -m models/tinyllama-1.1b-chat-v1.0.Q6_K.gguf -t 3
You should now see the llama.cpp server up -
Go to localhost:8080, you should see the below UI
Let's try playing with the model now.
Ask a quick question and see it respond 😃
Hey! It just suggested some great places to visit in India!
Do give it a try. It's amazing !! 🥂
]]>This is the second part of a two-part series on creating Serverless FAST API.
If you haven't checked the first part, do take a look here
From our previous setup, we created a fast API application that does CRUD operation on Todos.
Now let us modify this a bit to support AWS serverless.
For this application, we will use AWS SAM.
I have already talked about serverless here for you to explore.
Updating the setup
We need to add a SAM template in order to let us deploy fast API to AWS Lambda. However, we also need an adapter that can translate AWS serverless events to be transferred to our Fast API server.
Enters Magnum!
We will use Magnum, an adapter for running ASGI applications in AWS Lambda to handle Function URL, API Gateway, ALB, and Lambda@Edge events.
This is how we configure the adapter
from mangum import Mangum
from app.main import app
handler = Mangum(app=app)
Now let's add the SAM Template
We will create a ProxyApi of type Serverless API.
The Runtime selected is python 3.8 and architecture is arm64
The proxy setup allows a pass-through of all API Calls to our fast API server using Magnum.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
fast-api
Globals:
Function:
Timeout: 30
MemorySize: 128
Resources:
ProxyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
BinaryMediaTypes: [ '*/*' ]
HandlerFunction:
Type: AWS::Serverless::Function
Properties:
Handler: handler.handler
Runtime: python3.8
Architectures:
- arm64
Events:
FunctionProxy:
Type: Api
Properties:
RestApiId: !Ref ProxyApi
Path: "/{proxy+}"
Method: ANY
Outputs:
HandlerFunctionApi:
Description: "API Gateway endpoint URL for Prod stage"
Value: !Sub "https://${ProxyApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
HandlerFunction:
Description: "Lambda Function ARN"
Value: !GetAtt HandlerFunction.Arn
HandlerFunctionIamRole:
Description: "Implicit IAM Role created"
Value: !GetAtt HandlerFunction.Arn
Deployment
Now all you need to do is run the below commands
sam build
sam deploy --guided
Once the deployment completes we can check in cloud formation, it should have an entry like the one below -
Now let us try the endpoints using Postman or any other rest client
Creating Todo
Fetching Todos
Deleting Todo
That's it! This completes our serverless Fast API! Hope you like it 🍻
]]>Fast API
FastAPI is a modern, high-performance web framework for building APIs with Python based on standard type hints. It has the following key features:
This is the first part of a two-part series on creating a serverless API using Fast API
Fast API
FastAPI is a modern, high-performance web framework for building APIs with Python based on standard type hints. It has the following key features:
Let's create a small to-do app that uses an in-memory data store.
Structuring the codebase
Let's structure the app like below
The Model
For the model we use below code -
from pydantic import BaseModel
from typing import Union
class Todo(BaseModel):
id: Union[str, None] = None
todo: str
The Router
The router has the below routes -
from fastapi import APIRouter, HTTPException
import app.service.todo as todo_service
from app.model.todo import Todo
router = APIRouter(
prefix="/todos",
tags=["todos"],
responses={404: {"description": "Not found"}},
)
@router.get("/")
async def read_todos():
return await todo_service.read_todos()
@router.post("/")
async def create_todo(todo: Todo):
return await todo_service.create_todo(todo)
@router.get("/{todo_id}")
async def read_todo(todo_id: str):
todo = await todo_service.read_todo(todo_id)
if todo is None:
raise HTTPException(status_code=404, detail="Todo not found")
return todo
@router.delete("/{todo_id}")
async def delete_todo(todo_id: str):
todo = await todo_service.read_todo(todo_id)
if todo is None:
raise HTTPException(status_code=404, detail="Todo not found")
return await todo_service.delete_todo(todo_id)
We use the @router annotation for various HTTP verbs
The router calls the service which has the business logic
The Service
Service details -
import uuid
from typing import List
from app.model.todo import Todo
todos_db: List[Todo] = []
async def read_todos():
return todos_db
async def create_todo(todo: Todo):
todo.id = str(uuid.uuid4())
todos_db.append(todo)
return todo
async def read_todo(todo_id: str):
for todo in todos_db:
if todo.id == todo_id:
return todo
return None
async def delete_todo(todo_id: str):
t = None
for todo in todos_db:
if todo.id == todo_id:
t = todo
if t is not None:
todos_db.remove(t)
else:
return None
Service handles the generic CRUD operation with an in-memory data store called todos_db.
Putting it all together
The main app needs to be configured this way -
from fastapi import FastAPI
from .router import todo
app = FastAPI(
title="Todos API",
description="Todos API with in memory Database",
)
app.include_router(todo.router)
@app.get("/", tags=["health"])
async def root():
return {"status": "Success", "message": "App is running!"}
The title and description will be used for the out-of-box Open API specification.
Final Step
Fast API can be run with uvicorn server. Let's run it with the below configuration
import uvicorn
host="0.0.0.0"
port=8002
app_name="app.main:app"
if __name__ == '__main__':
uvicorn.run(app_name, host=host, port=port)
Okay, now let's run the code.
python .\main.py
We get amazing open API specs out of the box 😍
Go to http//:localhost:8002/docs and we get the open API specs
We can now run the API using the docs or any REST API client
Hope you like it! Do give it a try.
Oh! Here's the GitHub repository to play with the code
]]>What is Chat GPT ?
A natural language processing (NLP) model called GPT-3, also known as the "Generative Pre-training Transformer 3," was developed using text that humans produced. It can create its own human-like text using
]]>This blog shares how to create your own serverless ChatGPT API in Go.
What is Chat GPT ?
A natural language processing (NLP) model called GPT-3, also known as the "Generative Pre-training Transformer 3," was developed using text that humans produced. It can create its own human-like text using a range of languages and writing styles given some text input.
More details on Chat GPT and the excellent work can be found here.
What is Go?
Go, also referred to as Golang, is an open-source, statically typed, compiled computer language created by Google. It is designed to be straightforward, powerful, readable, and effective.
Prerequisites
The following prerequisites are needed -
Create Serverless API
type TextCompletionRequest struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
Temperature float64 `json:"temperature"`
MaxTokens int `json:"max_tokens"`
TopP float64 `json:"top_p"`
FrequencyPenalty float64 `json:"frequency_penalty"`
PresencePenalty float64 `json:"presence_penalty"`
}
type Choice struct {
Text string `json:"text"`
Index int `json:"index"`
Logprobs interface{} `json:"logprobs"`
FinishReason string `json:"finish_reason"`
}
type TextCompletionResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int `json:"created"`
Model string `json:"model"`
Choices []Choice `json:"choices"`
Usage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
} `json:"usage"`
}
func ConverseWithGPT(prompt string) (TextCompletionResponse, error) {
httpReq := TextCompletionRequest{
Model: "text-davinci-003",
Prompt: prompt,
Temperature: 0.7,
MaxTokens: 100,
TopP: 1.0,
FrequencyPenalty: 0.0,
PresencePenalty: 0.0,
}
jsonValue, _ := json.Marshal(httpReq)
bearer := "Bearer " + BearerToken
req, _ := http.NewRequest("POST", ChatGPTHTTPAddress, bytes.NewBuffer(jsonValue))
req.Header.Set("Authorization", bearer)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return TextCompletionResponse{}, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return TextCompletionResponse{}, ErrNon200Response
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return TextCompletionResponse{}, err
}
var textCompletionResponse TextCompletionResponse
if err := json.Unmarshal(body, &textCompletionResponse); err != nil {
fmt.Println("Can not unmarshal JSON")
}
return textCompletionResponse, nil
}
To check, the code, checkout this repo.
Let's see it in action
Let's now run this locally.
Run the below command -
sam build
sam local start-api
Now, we can run this using Postman
All right, Chat GPT suggested some Netflix series to watch. Let me go watch them while you try running this yourself.
Cheers 🍻
]]>As per the official site -
gRPC is a modern open-source high-performance Remote Procedure Call (RPC) framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking, and authentication. It is also
]]>As per the official site -
gRPC is a modern open-source high-performance Remote Procedure Call (RPC) framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking, and authentication. It is also applicable in the last mile of distributed computing to connect devices, mobile applications, and browsers to backend services.
Some salient features -
gRPC Architecture
gRPC is based on the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client requests. On the client side, the client has a stub that provides the same methods as the server.
Protocol Buffers
Protobuf is the most commonly used IDL (Interface Definition Language) for gRPC. It's where you store your data and function contracts in the form of a proto file.
Both Client and Server need to have the same proto file which acts as a contract between them.
Protobuf is popular since it sends over JSON strings as bytes, making it much smaller and enabling faster performance.
Learn more about it here.
Now that we know some theory, let's get our hands dirty! We will use Java to create a gRPC server and call it using postman.
Code Setup
See the detailed pom file here
syntax = "proto3";
option java_package = "in.bitmaskers.grpc";
option java_outer_classname = "Todos";
service TodoStore {
rpc add (Todo) returns (APIResponse);
rpc searchTodo(TodoSearch) returns (Todo);
rpc listTodos(Empty) returns (stream Todo);
}
message Todo {
string name = 1;
}
message TodoSearch {
string name = 1;
}
message Empty {
}
message APIResponse{
string responseMessage = 1;
int32 responseCode = 2;
}
Creating the Server
Now let's implement the methods created in the previous steps
@Override
public void add(Todos.Todo request, StreamObserver<Todos.APIResponse> responseObserver) {
String name = request.getName();
Todos.Todo todo = Todos.Todo.newBuilder().setName(name).buildPartial();
todoList.add(todo);
Todos.APIResponse.Builder apiResponse = Todos.APIResponse.newBuilder();
apiResponse.setResponseCode(0);
apiResponse.setResponseMessage("Todo added successfully");
responseObserver.onNext(apiResponse.build());
responseObserver.onCompleted();
}
Here, we take the input name from the request, create a new Todo using the Builder pattern, and then add it to in memory TodoList.
Additionally, we also create an apiResponse which is sent back using responseObserver.
@Override
public void searchTodo(Todos.TodoSearch request, StreamObserver<Todos.Todo> responseObserver) {
String name = request.getName();
Optional<Todos.Todo> optionalTodo = todoList.stream().filter(todo -> todo.getName().equals(name)).findFirst();
if (optionalTodo.isPresent()) {
responseObserver.onNext(optionalTodo.get());
} else {
responseObserver.onNext(Todos.Todo.newBuilder().buildPartial());
}
responseObserver.onCompleted();
}
Here we use streams API to search for the todo with the name passed and return it if found else returns empty
This is an interesting one. We are not sending the entire Todo List in one go but streaming it using Server Streaming capability.
@Override
public void listTodos(Todos.Empty request, StreamObserver<Todos.Todo> responseObserver) {
for (Todos.Todo todo : todoList) {
responseObserver.onNext(todo);
try {
// Replicate time-consuming IO Calls
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
responseObserver.onCompleted();
}
Here we are using Thread sleep of 5000ms to replicate some time-consuming IO calls.
Easiest one of all. We create a main method that can be used to run the code.
public class GRPCServer {
public static void main(String[] args) throws IOException, InterruptedException {
Server server = ServerBuilder.forPort(9090).addService(new TodosStoreService()).build();
server.start();
System.out.println("Server started at " + server.getPort());
server.awaitTermination();
}
}
All right our server is ready. Now let's run it and use Postman to perform some calls.
Setting postman
Import is as an API
Let's now run all the methods and see them in action
See the response is a streaming one with some gap in between!
All right folks! This was a long one but enjoyed learning something new.
Hope you like it. Cheers 🍻
]]>For more details on Serverless read
]]>Serverless most often refers to applications that don’t require you to provision or manage any servers. You can focus on your core product and business logic instead of responsibilities like operating system (OS) access control, OS patching, provisioning, right-sizing, scaling, and availability.
For more details on Serverless read below
The Serverless API
Earlier, we had to orchestrate a few services together to get an API up and running.
Several serverless functions implement the business logic in these apps. Using services like Amazon API Gateway and Application Load Balancer, each function is mapped to API endpoints, methods, and resources.
However, at times you need a simple HTTPS endpoint without having to configure or learn additional AWS services.
This is what AWS Lambda Function URLs allow you to do. It removes the dependency on API Gateway to expose HTTPS endpoints.
The Lambda function URL is unique globally and follows the following format:
https://<url-id>.lambda-url.<region>.on.aws
Features available
Although it doesn’t support all the features that API Gateway does still it has some good features which can be useful
One of the most amazing feature
One feature that makes lambda function better than API Gateway is the timeout.
API Gateway has a limited 30seconds timeout and it might be a problem in some use cases.
However, Lambda function URLs don’t have any such limit but lambda, in general, has a timeout limit of 15 minutes which is more than enough.
You say — You need more time? — Well consider your architecture selection then 😉
For checking this, I updated the code with sleep for 1 min
Next, we try calling it from the postman again
Hope you liked this!
I will cover lambda function configuration using serverless.com templating in upcoming blogs.
Cheers. 🍻
]]>Python is a programming language that is commonly used to create websites and applications, automate operations, and perform data analysis. Python is a general-purpose programming language, which means it can be used to develop a wide range of applications and isn’t specialized for any particular problem.
]]>Python is a programming language that is commonly used to create websites and applications, automate operations, and perform data analysis. Python is a general-purpose programming language, which means it can be used to develop a wide range of applications and isn’t specialized for any particular problem. Because of its versatility and beginner-friendliness, it has become one of the most widely used programming languages today.
Why is Python so popular?
Although, Python is known for being slow 🐢 yet it’s very popular. Here are some reasons:
These are just a few of many other reasons why python is trending.
Here’s a StackOverflow survey showing popular ones :
Click here for the survey insights.
Integrating python with MuleSoft Scripting Module
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.2</version>
</dependency>
<configuration>
<sharedLibraries>
<sharedLibrary>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
</sharedLibrary>
</sharedLibraries>
</configuration>
import requestsdef request_website(site):
r = requests.get(site, verify=False)
return r.status_code
result = request_website(site)
There we have a working MuleSoft application integrated with python.
Hope you liked it. Cheers 🍻
]]>These codes can have some good business logic implemented and reinventing the wheel in Mule might sometimes get messy and tiresome.
Mule has support for handling this scenario as well. We can use
]]>Often you will find a lot of legacy code residing in .NET code in the project ecosystem.
These codes can have some good business logic implemented and reinventing the wheel in Mule might sometimes get messy and tiresome.
Mule has support for handling this scenario as well. We can use the MuleSoft Microsoft .NET Connector to use these legacy codes in a mule app.
Here, I will show an end-to-end method of integrating with .NET code.
So, let's get started.
What is DLL ?
A DLL is a library that contains code and data that can be used by more than one program at the same time. This contains code that can be reused by many other programs thus adding a sense of reusability.
For Java folks: Consider this as JARs.👌
Creating the .NET DLL
You will need Visual Studio to create a DLL file. 💬
Let's see the process:
2. Next we will name the solution and create the application
3. Finally we will create a simple calculator app and code in C# as below:
4. On building the project we can see that the DLL files get created as \bin\Debug\netstandard2.0\CalculatorApp.dll
This completes the work needed for the .NET code. Now, we will use this in our Mule app.
We will create a new Mule App. I named it as netapp(you can name anything 😄)
Firstly, copy the generated DLL files to the src/resource directory of your mule app.
Copy the dll and pdb files as below:
This will be then referenced in the connector.
Once added we can see it in the Mule Palette.
Select Connection as Resource since we have our DLL present in the resource folder.
The scope can be singleton so that one instance is created for all application calls.
Next, add the file name in the path as below:
On clicking Test Connection, we should get the below response:
This completes our Connector configuration.
Create a simple HTTP Listener and add Execute from the .NET Connector
We will add the Connector configuration as the one created earlier and on clicking the refresh button for Method Info Type, we will find the details populated as above.
All the functions we wrote using Visual Studio for the Library are available in the method.
For this sum operation, we will select
int sum(int a, int b) (CalculatorApp.Calculator, CalculatorApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | sum(System.Int32 a, System.Int32 b) -> System.Int32)
For input to the method we can use the Arguments and I am passing two query parameters as input namely number1 and number2.
These values will be then passed to our DLL and it will return the response.
Now, let's run the app and pass two query parameters.
Thus, we can see the output coming as expected. This shows the capability of talking to a .NET DLL from a Mule app.
Similarly, we can complete all other calculator operations, and the end-to-end application flow should look like the below:
Point to note: The .NET Connector needs a .NET framework in order to execute.
Hope you like it. Cheers!
]]>MuleSoft is best known for APIs. But we can also use it as a normal web server serving HTML pages. In this tutorial, I will cover the way to host React applications in MuleSoft.
Creating a simple react app
Here, I will create a very simple React app showing an image
Did't I say simple ? Yes!
Hosting this app in MuleSoft
Create a mule app "mulesoft-web-server"
Now we can start the application and see the output!
Hope you liked it. Cheers 🍻
GitHub link to repo is here!
]]>Docker is a revolution in the IT landscape and has made things easy.
It disallows developers to claim: "It works on my machine 😄"
Here, I created a cheat sheet I use to work with Docker
Frequently used commands
It shows the docker version installed.
It allows you to pull images from the repository.
To get all the pulled images that are available locally.
It allows you to see all the containers which are up and running.
It allows you to see all the containers that are available as well up and running.
The difference between docker ps and ps -a is that ps -a allows you to see containers that are down as well.
To Create a Docker Container from Docker Image in a detached mode.
To run the container in interactive mode using bash shell.
Tip: you can use part of the container_id too
To start a container with mentioned <container_id>.
To restart a container with mentioned <container_id>.
To stop a container with mentioned <container_id>.
To delete a container with mentioned <container_id>.
To delete a docker image with the mentioned <image_id>
To give details on the container id. It is JSON data with all the details of the container
Hope you liked this cheat sheet. 🍻
]]>Asynchronous communication is enabled via message queue software, which allows machines to communicate remotely, which acts as a backbone of any distributed system. A single application cannot be responsible for the entire operation in advanced systems. Rather, numerous apps are linked together to complete their respective sets of tasks and meet the system's overall requirement. Each system need to communicate among themselves and this is where the need for queues arises!
Currently, market has to offer a bunch of options when it comes to Queue. You have Apache Kafka, Apache Active MQ, AWS SQS, AWS SNS, Google Pub/Sub, Rabbit MQ etc.
Let's make a comparison which can help us choosing the right tool for our project.
I already did a series on Kafka vs RabbitMQ which can be found below:
ActiveMQ
Apache ActiveMQ is a prominent Java-based open source messaging server. It acts as a bridge between numerous apps that are hosted on different servers or developed in different languages. It supports numerous messaging protocols, including AMQP and MQTT, and implements JMS (Java Message Service).
Features -
When to use?
ActiveMQ is preferably used where small amounts of data is involved. Messages can be transmitted as part of a queue or as a topic with ActiveMQ. One or more consumers are connected to the queue through point to point messaging, and the broker utilizes a round robin strategy to direct messages to specific consumers. Brokers send communications to all consumers who have subscribed to the topic via subscription-based messaging.
For enterprises, which don’t have use for big data processing, ActiveMQ is a good option.
AWS SNS
Amazon SNS, or Amazon Simple Notification Service, is a push notification service offered by Amazon. It is is a fully managed messaging service for both application-to-application (A2A) and application-to-person (A2P) communication.
Features-
When to use ?
It’s a low-cost infrastructure, primarily used by companies to send pub/sub messages to their customers. This web service makes it easier for publishers to create and push notifications from the cloud. It’s ideal for developers who are looking for a message notification system that integrates with minimal effort, requires minimum maintenance and works on pay-as-you-go pricing. Unless your application requires a conventional queuing system, Amazon SNS offers a cheaper solution to push subscribed messages to customers.
AWS SQS
Amazon SQS is a fully managed distributed message queuing service offered by Amazon. It’s a cost-effective and simple technique to manage communication between components of software systems running in the cloud(even on prem if required). SQS eliminates the complexity and overhead associated with managing and operating message-oriented middleware, and empowers developers to focus on differentiating work.
Features
When to use?
Amazon SQS is of prime value to a serverless architecture where you want different services to function independently. It offers a lightweight and fast approach to establish communication between these decoupled services.
It’s a good option in applications where multiple independent systems need to be integrated without the overhead of maintaining own queue infrastructure. If your systems uses serverless stack with Lambdas then this is definitely a good option.
The FIFO queues are good for an ordered delivery of message but comes at a price of limited throughput. So, we need to choose wisely!
Google Pub/Sub
Google Cloud Pub/Sub is an asynchronous messaging service that allows you to send and receive messages between different apps. It provides dependable message storage and low-latency real-time message delivery, making it a popular choice among developers that need to send out event notifications, stream data from many devices, or build asynchronous workflows.
Features
When to use?
Google Pub/Sub offers reliable messaging and data streaming across applications hosted anywhere on the internet, including Google Cloud Platform. Many advanced features are included to make communication easier to manage. Auto-scaling, dead-letter delivery and filtering makes your applications simpler. Many developers prefer it for the flexible pricing. Google Pub/Sub charges you on the volume transmitted after you have used your free 10 gigabytes.
Those who already have their applications running on Google Cloud Platform should go for Google Pub/Sub.
Hope this article helps. Cheers 🍻
]]>Most people who work in technology, especially cloud computing, are probably familiar with service-oriented architecture (SOA) and microservices but still there always remains some doubt regarding the differences between these two.
In this article, we will learn in deep, regarding SOA(Service Oriented Architecture) and Microservices.
What is SOA ?
A service-oriented architecture (SOA) is a method of developing software that focuses on reusability while also ensuring that non-functional needs (such as security, scalability, and performance) are addressed. It includes a group of services that are modular in nature and "communicate" with one another to support applications. The communication can involve either simple data passing or two or more services coordinating some activity. Some means of connecting services to each other is needed which is typically ESB(Enterprise Service Bus).
What is Microservice ?
Microservices are a sort of evolution or extension of SOA. Microservices use APIs, or application programming interfaces, to connect with one another. Each of them contributes to the formation of an organizational network centered on a given business topic. When these services are combined, they form sophisticated applications. Microservices construct an application system as a collection of single-purpose services that are generally different and distinctive.
SOA and Microservice can be differentiated on Scope, Granularity, and Implementation!
SOA is a collection of enterprise-level applications and services that need developers to have a thorough understanding of the application and all of its dependencies in order to code properly.
Microservices, on the other hand, is a design pattern for an application. It divides a single application into numerous distinct services, each of which performs a different purpose. In other words, each capability excels at one task, decreasing the amount of knowledge required by engineers to work on each module.
SOA is "coarse-grained", which means it concentrates on broad, business-domain functions. As a result, each functionality has a large number of dependents.
Microservices are even more "fine-grained", resulting in a tangle of capabilities with a single emphasis known as a bounded context. Each bounded context is self-contained, lightly connected, and much more focused than an SOA's domain functions. This allows it to be more scalable than SOAs.
SOA requires software that handles communication. Historically, businesses have used web service access protocols like SOAP to expose, and then transact with each functionality. This created a point-to-point integration which was difficult to manage. This is why SOA makes use of an Enterprise Service Bus (ESB), a middleware technology that handles communication and lowers the amount of point-to-point connections between capabilities.
When it comes to a microservices architecture, each individual service operates and scales independently and so each has its own separate point of failure, making microservices far more resilient and agile, and enabling the independent coding of each individual functionality.
Hope you liked it. There will be a second part published on when to use SOA and when to use Microservices. So stay tuned.
Cheers 🍻
]]>In computing, a database is an organized collection of data stored and accessed electronically from a computer system. It is a system for storing data in an ordered manner. The data is stored in a specified structure within the storage. Each database type has its own data storage format. They've been tweaked and tuned for various scenarios.
Let's take this simple Employee Table as an example
Wondered how this simple table is actually saved Internally.
Storage
Internally, each database is kept as a file with a certain encoding and layout. Let's pretend that a database is backed by a CSV file for the purpose of simplicity. Here's how it appears:
Id,FirstName,LastName,Designation
1,Analise,Holsall,Account Executive
2,Agnes,St. Hill,Structural Analysis Engineer
3,Ulrica,Willimot,Mechanical Systems Engineer
4,Coop,Awcoate,VP Product Management
5,Willi,De Maria,Business Systems Development Analyst
Everything appears to be straightforward. It's not difficult to perform a lookup with only five entries but what if there were 100,000 entries? It would take a long time to go through the entire file. The query time grows in direct proportion to the file size.
This brings us to finding an optimal solution to retrieve data faster.
Indexing comes to the rescue!!
Indexing
A database index is a data structure that can be used to speed up data retrieval activities. What does it resemble?
It would be much faster to skip to the appropriate row without looping through the remainder of the table if we needed to fetch an employee with ID 5. This is the central concept of indexing. We must additionally save the offset, which leads to the appropriate entry.
The simplest way to achieve this would be to use hashing. The key is the value of the column we want to index (in this example, it is the Id column). The hash value is the offset(starting index) in the database file. For ID = 1
, the offset is 0
. For ID = 2
, the offset is 36
.
The end-to-end structure will look like this:
1 -> 0 -------> 1,Analise,Holsall,Account Executive
2 -> 36 ------> 2,Agnes,St. Hill,Structural Analysis Engineer
3 -> 72 ------> 3,Ulrica,Willimot,Mechanical Systems Engineer
4 -> 118 ------> 4,Coop,Awcoate,VP Product Management
5 -> 155 ------> 5,Willi,De Maria,Business Systems Development Analyst
Querying employees by ID
will yield faster results if we build an index. The retrieved request accesses the hash index and retrieves the offset for the desired ID
.
There is also the option of having several indexes. If any other column needs to be accessed quickly, we create an index for it as well. For example, we could create a designation index and query employees by designation faster! However, each new index adds an additional load to the database.
The Cost of Indexing
Firstly, each index hash requires additional Memory space. It's crucial to remember to index only the columns that will be queried frequently. Otherwise, indexing each column would take up a huge amount of Memory space.
Secondly, there will be slightly slower write operations for the quick read operations. We must construct an item in the hash index every time we add an entry to the table. This makes insert operations slow.
TL;DR
In this article, we saw a simple file-based data storage with offset-based indexing. There are many other approaches like BTree or B+Tree but the concept remains relevant.
I always wondered how to enhance my API performances and indexing was one of many ways we can use to make our APIs faster.
Hope you like it. Cheers 🍻
]]>Lambda is part of the Serverless offering from AWS. Check a detailed post here:
Although, Lambdas are great it comes with something called Cold Start.
Cold starts may wreak havoc on Lambda's performance, especially if you're working on a customer-facing app that needs to respond in real-time. They occur because AWS must deploy your code and spin up a new container before the request can begin if your Lambda is not currently running.
This is the typical Request Life Cycle
The first request handled by a new Lambda worker is known as a "cold start." This request takes a little longer to complete because the Lambda service must:
Cold starts account for fewer than 0.25 percent of Lambda requests, but their impact can be significant. This issue is especially important for applications that require real-time execution or rely on split-second timing.
How to solve the cold start?
Using Provisioned Concurrency
Knowing that the time it takes to configure the computational worker nodes is a key cause of cold starts, the AWS Provisioned Concurrency solution is straightforward. Those worker nodes are already up and running! There is no extra code needed, just some clicks and your app is always ready to respond to users without any delay.
The idea is that you can now choose how many of these worker nodes you want to keep initialized for your time-sensitive serverless apps. These worker nodes will be frozen, with your code already downloaded and the underlying container infrastructure in place. As a result of not consuming any resources, the benefit here is a guaranteed response time of approximately double that of the previous method.
However, it comes at a price. From the moment you enable provided concurrency, you'll be charged for it unlike normal lambdas, which charge you only when it executes your code.
Therefore, make sure you are aware of the lambdas which has provisioned concurrency and also the number of concurrency you are assigning.
I created this tool, that you can use to fetch all the functions that have provisioned concurrency. Check the code below:
Steps on adding provisioned concurrency:
Hope you like this. Cheers 🍻
]]>We all started with Web Development with some MVC framework initially(at least I did). Web apps back then would start a thread with new requests, the thread would process the request, and a “view” (HTML) would be generated and given to the client to render.
Layer after layer of inadequate software architecture, system design, size, and technical rot would crumple systems. In addition, tremendous amounts of valuable intellectual property — business rules, procedures, and workflows — were tightly coupled and a lacked reusability.
The progress
Since then, we've made significant progress. We could use reusable libraries to create better monolithic applications, but what if we wanted to create scalable(horizontal and vertical) architectures that could be distributed over several computing resources? What if we wanted to support desktop, online, and mobile devices with as much reusability and central control as possible?
Eventually came the world of APIs. The concepts of distributed software APIs and how simple Request/Response protocols may power almost any business activity were popularized by SOAP and REST.
With this evolution, we often found every team having 3 main pillars - the data person(dealing with data store), the service person(Writing APIs and building scalable systems) and an UI person(creating the User Interfaces).
What makes an API beautiful ?
In today's world of SAAS, APIs are really a product that powers your UI and is as important as that shinier User Interface and underlying data pool/lake/ocean. Creating beautiful API is an art and these key factors determine how beautiful you APIs are -
Once our beautiful API is thought through, we can now go to the API first development approach.
API First Development
It states that the first part of API Development is the design of APIs. Ask yourself how you, as a consumer, would want to work with data and conduct actions to solve your business challenges, rather than how your entity diagrams and database would work. Then, to the best of your technical ability, develop an API to solve the challenge(s).
Once API is designed, the database person can now create stored procedures or queries to fetch the data from data source. Service person can create highly scalable APIs with queues and messaging systems and other powerful tools(you have many nowadays, thanks to cloud computing 😉). The UI folks can use the mocked APIs to create mockup, designs and interfaces.
With less overall interaction and dependency, teams can begin to stagger the completion of their swim lanes. Iterative feedback can be gathered, allowing the overall software development process to progress more quickly. API-first aims to achieve this.
This all looks good but what are the tools available to make this work?
Enters OpenAPI and RAML
OpenAPI provides a variety of capabilities to guarantee that APIs are thoroughly documented. Versions and query tokens and parameters, security specifications (JWT/oAuth/basic/etc. ), HTTP headers, multi-part request bodies, a bewildering array of response types, and some amazing modelling tools that reflect the needs of both static and dynamic type systems present in today's back-end services can all be specified in paths. It was formerly known as Swagger.
RAML (RESTful API Modeling Language) is a YAML-based modelling language that is used to represent RESTful APIs. It gives a well-structured and easy-to-understand framework for describing the API. It "makes it straightforward to manage the entire API lifecycle," according to RAML's website.
Hope you liked it. Cheers 🍻
]]>