Skip to content

Commit

Permalink
Configured elastic index to have replicas configurable by tenant (#7676)
Browse files Browse the repository at this point in the history
* Configured elastic index to have replicas configurable by tenant

* Changed esUseReplicas to esReplicas: number

* Added flag for REINDEX_WITH_OPTIMIZATION

* Renamed wrongly named feature

* Upped version
  • Loading branch information
RafaPolit committed Feb 24, 2025
1 parent 21d8a8c commit 4eba550
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 17 deletions.
1 change: 1 addition & 0 deletions app/api/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const config = {
activityLogs: ACTIVITY_LOGS_FOLDER || `${filesRootPath}/log/`,
featureFlags: {
s3Storage: false,
esReplicas: 0,
},
},
externalServices: Boolean(process.env.EXTERNAL_SERVICES) || false,
Expand Down
8 changes: 4 additions & 4 deletions app/api/search/entitiesIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import { MongoSettingsDataSource } from 'api/settings.v2/database/MongoSettingsD
import { LanguageUtils } from 'shared/language';
import { DefaultTransactionManager } from 'api/common.v2/database/data_source_defaults';
import { otherLanguageSchema } from 'shared/language/availableLanguages';
import elasticMapping from '../../../database/elastic_mapping/elastic_mapping';
import { getTenantESMapping } from 'api/tenants/tenantESMapping';
import elasticMapFactory from '../../../database/elastic_mapping/elasticMapFactory';
import { elastic } from './elastic';

export class IndexError extends Error {}
class IndexError extends Error {}

const preprocessEntitiesToIndex = async entitiesToIndex => {
const db = getConnection();
Expand Down Expand Up @@ -183,9 +183,9 @@ const updateMapping = async tmpls => {

const reindexAll = async (tmpls, searchInstance) => {
await elastic.indices.delete();
await elastic.indices.create({ body: elasticMapping });
await elastic.indices.create({ body: getTenantESMapping() });
await updateMapping(tmpls);
return indexEntities({ query: {}, searchInstance });
};

export { bulkIndex, indexEntities, updateMapping, reindexAll };
export { IndexError, bulkIndex, indexEntities, updateMapping, reindexAll };
29 changes: 29 additions & 0 deletions app/api/tenants/specs/tenantESMapping.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { tenants } from '../tenantContext';
import { getTenantESMapping } from '../tenantESMapping';

describe('tenantESMapping', () => {
describe('getTenantESMapping', () => {
it('should use the base elastic mapping', async () => {
tenants.add({
name: 'test-tenant',
dbName: 'test-tenant-db',
});

await tenants.run(async () => {
expect(getTenantESMapping().settings['index.number_of_replicas']).toBe(0);
}, 'test-tenant');
});

it('should use the append tenant specific configuration to base mapping', async () => {
tenants.add({
name: 'test-tenant',
dbName: 'test-tenant-db',
featureFlags: { esReplicas: 2 },
});

await tenants.run(async () => {
expect(getTenantESMapping().settings['index.number_of_replicas']).toBe(2);
}, 'test-tenant');
});
});
});
2 changes: 2 additions & 0 deletions app/api/tenants/specs/tenantsModel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe('tenantsModel', () => {
healthChecks: 'un-needed data',
featureFlags: {
s3Storage: false,
esReplicas: 1,
},
},
{
Expand Down Expand Up @@ -82,6 +83,7 @@ describe('tenantsModel', () => {
activityLogs: 'path',
featureFlags: {
s3Storage: false,
esReplicas: 1,
},
});
expect(tenantTwo).toEqual({
Expand Down
1 change: 1 addition & 0 deletions app/api/tenants/tenantContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Tenant = {
activityLogs: string;
featureFlags?: {
s3Storage?: boolean;
esReplicas?: number;
sync?: boolean;
v1_transactions?: boolean;
};
Expand Down
16 changes: 16 additions & 0 deletions app/api/tenants/tenantESMapping.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { tenants } from './index';
import elasticMapping from '../../../database/elastic_mapping/elastic_mapping';

const getTenantESMapping = () => {
const tenantElasticMapping = {
settings: { ...elasticMapping.settings },
mappings: { ...elasticMapping.mappings },
};

tenantElasticMapping.settings['index.number_of_replicas'] =
tenants.current().featureFlags?.esReplicas || 0;

return tenantElasticMapping;
};

export { getTenantESMapping };
1 change: 1 addition & 0 deletions app/api/tenants/tenantsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const mongoSchema = new mongoose.Schema({
activityLogs: String,
featureFlags: {
s3Storage: Boolean,
esReplicas: Number,
sync: Boolean,
v1_transactions: Boolean,
},
Expand Down
40 changes: 28 additions & 12 deletions database/reindex_elastic.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,40 @@ const headers = {
'Content-Type': 'application/json',
};

const setReindexSettings = async (refreshInterval, numberOfReplicas, translogDurability) =>
fetch(`${getIndexUrl()}/_settings`, {
method: 'PUT',
headers,
body: {
index: {
refresh_interval: refreshInterval,
number_of_replicas: numberOfReplicas,
translog: {
durability: translogDurability,
},
const setReindexSettings = async (refreshInterval, numberOfReplicas, translogDurability) => {
let body = {
index: {
refresh_interval: refreshInterval,
number_of_replicas: numberOfReplicas,
translog: {
durability: translogDurability,
},
},
};

if (process.env.REINDEX_WITH_OPTIMIZATION) {
body = JSON.stringify(body);
}

const result = await fetch(`${getIndexUrl()}/_settings`, {
method: 'PUT',
headers,
body,
});

return result;
};

const restoreSettings = async () => {
process.stdout.write('Restoring index settings...');
const result = setReindexSettings('1s', 0, 'request');

const tenantReplicas = tenants.current().featureFlags?.esReplicas || 0;

if (tenants.current().featureFlags?.esReplicas) {
process.stdout.write('restoring ES Replicas...');
}

const result = setReindexSettings('1s', tenantReplicas, 'request');
process.stdout.write(' [done]\n');
return result;
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "uwazi",
"version": "1.201.0-rc3",
"version": "1.202.0-rc2",
"description": "Uwazi is a free, open-source solution for organising, analysing and publishing your documents.",
"keywords": [
"react"
Expand Down

0 comments on commit 4eba550

Please sign in to comment.